##// END OF EJS Templates
merge with stable
Matt Mackall -
r15623:fc8c7a5c merge default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,101 +1,119 b''
1 ====
1 ====
2 hg
2 hg
3 ====
3 ====
4
4
5 ---------------------------------------
5 ---------------------------------------
6 Mercurial source code management system
6 Mercurial source code management system
7 ---------------------------------------
7 ---------------------------------------
8
8
9 :Author: Matt Mackall <mpm@selenic.com>
9 :Author: Matt Mackall <mpm@selenic.com>
10 :Organization: Mercurial
10 :Organization: Mercurial
11 :Manual section: 1
11 :Manual section: 1
12 :Manual group: Mercurial Manual
12 :Manual group: Mercurial Manual
13
13
14 .. contents::
14 .. contents::
15 :backlinks: top
15 :backlinks: top
16 :class: htmlonly
16 :class: htmlonly
17 :depth: 1
17 :depth: 1
18
18
19
19
20 Synopsis
20 Synopsis
21 --------
21 --------
22 **hg** *command* [*option*]... [*argument*]...
22 **hg** *command* [*option*]... [*argument*]...
23
23
24 Description
24 Description
25 -----------
25 -----------
26 The **hg** command provides a command line interface to the Mercurial
26 The **hg** command provides a command line interface to the Mercurial
27 system.
27 system.
28
28
29 Command Elements
29 Command Elements
30 ----------------
30 ----------------
31
31
32 files...
32 files...
33 indicates one or more filename or relative path filenames; see
33 indicates one or more filename or relative path filenames; see
34 `File Name Patterns`_ for information on pattern matching
34 `File Name Patterns`_ for information on pattern matching
35
35
36 path
36 path
37 indicates a path on the local machine
37 indicates a path on the local machine
38
38
39 revision
39 revision
40 indicates a changeset which can be specified as a changeset
40 indicates a changeset which can be specified as a changeset
41 revision number, a tag, or a unique substring of the changeset
41 revision number, a tag, or a unique substring of the changeset
42 hash value
42 hash value
43
43
44 repository path
44 repository path
45 either the pathname of a local repository or the URI of a remote
45 either the pathname of a local repository or the URI of a remote
46 repository.
46 repository.
47
47
48 .. include:: hg.1.gendoc.txt
48 .. include:: hg.1.gendoc.txt
49
49
50 Files
50 Files
51 -----
51 -----
52
52
53 ``.hgignore``
54 This file contains regular expressions (one per line) that
55 describe file names that should be ignored by **hg**. For details,
56 see |hgignore(5)|_.
57
58 ``.hgtags``
59 This file contains changeset hash values and text tag names (one
60 of each separated by spaces) that correspond to tagged versions of
61 the repository contents.
62
63 ``/etc/mercurial/hgrc``, ``$HOME/.hgrc``, ``.hg/hgrc``
53 ``/etc/mercurial/hgrc``, ``$HOME/.hgrc``, ``.hg/hgrc``
64 This file contains defaults and configuration. Values in
54 This file contains defaults and configuration. Values in
65 ``.hg/hgrc`` override those in ``$HOME/.hgrc``, and these override
55 ``.hg/hgrc`` override those in ``$HOME/.hgrc``, and these override
66 settings made in the global ``/etc/mercurial/hgrc`` configuration.
56 settings made in the global ``/etc/mercurial/hgrc`` configuration.
67 See |hgrc(5)|_ for details of the contents and format of these
57 See |hgrc(5)|_ for details of the contents and format of these
68 files.
58 files.
69
59
60 ``.hgignore``
61 This file contains regular expressions (one per line) that
62 describe file names that should be ignored by **hg**. For details,
63 see |hgignore(5)|_.
64
65 ``.hgsub``
66 This file defines the locations of all subrepositories, and
67 tells where the subrepository checkouts came from. For details, see
68 :hg:`help subrepos`.
69
70 ``.hgsubstate``
71 This file is where Mercurial stores all nested repository states. *NB: This
72 file should not be edited manually.*
73
74 ``.hgtags``
75 This file contains changeset hash values and text tag names (one
76 of each separated by spaces) that correspond to tagged versions of
77 the repository contents. The file content is encoded using UTF-8.
78
79 ``.hg/last-message.txt``
80 This file is used by :hg:`commit` to store a backup of the commit message
81 in case the commit fails.
82
83 ``.hg/localtags``
84 This file can be used to define local tags which are not shared among
85 repositories. The file format is the same as for ``.hgtags``, but it is
86 encoded using the local system encoding.
87
70 Some commands (e.g. revert) produce backup files ending in ``.orig``,
88 Some commands (e.g. revert) produce backup files ending in ``.orig``,
71 if the ``.orig`` file already exists and is not tracked by Mercurial,
89 if the ``.orig`` file already exists and is not tracked by Mercurial,
72 it will be overwritten.
90 it will be overwritten.
73
91
74 Bugs
92 Bugs
75 ----
93 ----
76 Probably lots, please post them to the mailing list (see Resources_
94 Probably lots, please post them to the mailing list (see Resources_
77 below) when you find them.
95 below) when you find them.
78
96
79 See Also
97 See Also
80 --------
98 --------
81 |hgignore(5)|_, |hgrc(5)|_
99 |hgignore(5)|_, |hgrc(5)|_
82
100
83 Author
101 Author
84 ------
102 ------
85 Written by Matt Mackall <mpm@selenic.com>
103 Written by Matt Mackall <mpm@selenic.com>
86
104
87 Resources
105 Resources
88 ---------
106 ---------
89 Main Web Site: http://mercurial.selenic.com/
107 Main Web Site: http://mercurial.selenic.com/
90
108
91 Source code repository: http://selenic.com/hg
109 Source code repository: http://selenic.com/hg
92
110
93 Mailing list: http://selenic.com/mailman/listinfo/mercurial
111 Mailing list: http://selenic.com/mailman/listinfo/mercurial
94
112
95 Copying
113 Copying
96 -------
114 -------
97 Copyright (C) 2005-2010 Matt Mackall.
115 Copyright (C) 2005-2010 Matt Mackall.
98 Free use of this software is granted under the terms of the GNU General
116 Free use of this software is granted under the terms of the GNU General
99 Public License version 2 or any later version.
117 Public License version 2 or any later version.
100
118
101 .. include:: common.txt
119 .. include:: common.txt
@@ -1,5701 +1,5703 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex, bin, nullid, nullrev, short
8 from node import hex, bin, nullid, nullrev, short
9 from lock import release
9 from lock import release
10 from i18n import _, gettext
10 from i18n import _, gettext
11 import os, re, difflib, time, tempfile, errno
11 import os, re, difflib, time, tempfile, errno
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
13 import patch, help, url, encoding, templatekw, discovery
13 import patch, help, url, encoding, templatekw, discovery
14 import archival, changegroup, cmdutil, hbisect
14 import archival, changegroup, cmdutil, hbisect
15 import sshserver, hgweb, hgweb.server, commandserver
15 import sshserver, hgweb, hgweb.server, commandserver
16 import match as matchmod
16 import match as matchmod
17 import merge as mergemod
17 import merge as mergemod
18 import minirst, revset, fileset
18 import minirst, revset, fileset
19 import dagparser, context, simplemerge
19 import dagparser, context, simplemerge
20 import random, setdiscovery, treediscovery, dagutil
20 import random, setdiscovery, treediscovery, dagutil
21
21
22 table = {}
22 table = {}
23
23
24 command = cmdutil.command(table)
24 command = cmdutil.command(table)
25
25
26 # common command options
26 # common command options
27
27
28 globalopts = [
28 globalopts = [
29 ('R', 'repository', '',
29 ('R', 'repository', '',
30 _('repository root directory or name of overlay bundle file'),
30 _('repository root directory or name of overlay bundle file'),
31 _('REPO')),
31 _('REPO')),
32 ('', 'cwd', '',
32 ('', 'cwd', '',
33 _('change working directory'), _('DIR')),
33 _('change working directory'), _('DIR')),
34 ('y', 'noninteractive', None,
34 ('y', 'noninteractive', None,
35 _('do not prompt, automatically pick the first choice for all prompts')),
35 _('do not prompt, automatically pick the first choice for all prompts')),
36 ('q', 'quiet', None, _('suppress output')),
36 ('q', 'quiet', None, _('suppress output')),
37 ('v', 'verbose', None, _('enable additional output')),
37 ('v', 'verbose', None, _('enable additional output')),
38 ('', 'config', [],
38 ('', 'config', [],
39 _('set/override config option (use \'section.name=value\')'),
39 _('set/override config option (use \'section.name=value\')'),
40 _('CONFIG')),
40 _('CONFIG')),
41 ('', 'debug', None, _('enable debugging output')),
41 ('', 'debug', None, _('enable debugging output')),
42 ('', 'debugger', None, _('start debugger')),
42 ('', 'debugger', None, _('start debugger')),
43 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
43 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
44 _('ENCODE')),
44 _('ENCODE')),
45 ('', 'encodingmode', encoding.encodingmode,
45 ('', 'encodingmode', encoding.encodingmode,
46 _('set the charset encoding mode'), _('MODE')),
46 _('set the charset encoding mode'), _('MODE')),
47 ('', 'traceback', None, _('always print a traceback on exception')),
47 ('', 'traceback', None, _('always print a traceback on exception')),
48 ('', 'time', None, _('time how long the command takes')),
48 ('', 'time', None, _('time how long the command takes')),
49 ('', 'profile', None, _('print command execution profile')),
49 ('', 'profile', None, _('print command execution profile')),
50 ('', 'version', None, _('output version information and exit')),
50 ('', 'version', None, _('output version information and exit')),
51 ('h', 'help', None, _('display help and exit')),
51 ('h', 'help', None, _('display help and exit')),
52 ]
52 ]
53
53
54 dryrunopts = [('n', 'dry-run', None,
54 dryrunopts = [('n', 'dry-run', None,
55 _('do not perform actions, just print output'))]
55 _('do not perform actions, just print output'))]
56
56
57 remoteopts = [
57 remoteopts = [
58 ('e', 'ssh', '',
58 ('e', 'ssh', '',
59 _('specify ssh command to use'), _('CMD')),
59 _('specify ssh command to use'), _('CMD')),
60 ('', 'remotecmd', '',
60 ('', 'remotecmd', '',
61 _('specify hg command to run on the remote side'), _('CMD')),
61 _('specify hg command to run on the remote side'), _('CMD')),
62 ('', 'insecure', None,
62 ('', 'insecure', None,
63 _('do not verify server certificate (ignoring web.cacerts config)')),
63 _('do not verify server certificate (ignoring web.cacerts config)')),
64 ]
64 ]
65
65
66 walkopts = [
66 walkopts = [
67 ('I', 'include', [],
67 ('I', 'include', [],
68 _('include names matching the given patterns'), _('PATTERN')),
68 _('include names matching the given patterns'), _('PATTERN')),
69 ('X', 'exclude', [],
69 ('X', 'exclude', [],
70 _('exclude names matching the given patterns'), _('PATTERN')),
70 _('exclude names matching the given patterns'), _('PATTERN')),
71 ]
71 ]
72
72
73 commitopts = [
73 commitopts = [
74 ('m', 'message', '',
74 ('m', 'message', '',
75 _('use text as commit message'), _('TEXT')),
75 _('use text as commit message'), _('TEXT')),
76 ('l', 'logfile', '',
76 ('l', 'logfile', '',
77 _('read commit message from file'), _('FILE')),
77 _('read commit message from file'), _('FILE')),
78 ]
78 ]
79
79
80 commitopts2 = [
80 commitopts2 = [
81 ('d', 'date', '',
81 ('d', 'date', '',
82 _('record the specified date as commit date'), _('DATE')),
82 _('record the specified date as commit date'), _('DATE')),
83 ('u', 'user', '',
83 ('u', 'user', '',
84 _('record the specified user as committer'), _('USER')),
84 _('record the specified user as committer'), _('USER')),
85 ]
85 ]
86
86
87 templateopts = [
87 templateopts = [
88 ('', 'style', '',
88 ('', 'style', '',
89 _('display using template map file'), _('STYLE')),
89 _('display using template map file'), _('STYLE')),
90 ('', 'template', '',
90 ('', 'template', '',
91 _('display with template'), _('TEMPLATE')),
91 _('display with template'), _('TEMPLATE')),
92 ]
92 ]
93
93
94 logopts = [
94 logopts = [
95 ('p', 'patch', None, _('show patch')),
95 ('p', 'patch', None, _('show patch')),
96 ('g', 'git', None, _('use git extended diff format')),
96 ('g', 'git', None, _('use git extended diff format')),
97 ('l', 'limit', '',
97 ('l', 'limit', '',
98 _('limit number of changes displayed'), _('NUM')),
98 _('limit number of changes displayed'), _('NUM')),
99 ('M', 'no-merges', None, _('do not show merges')),
99 ('M', 'no-merges', None, _('do not show merges')),
100 ('', 'stat', None, _('output diffstat-style summary of changes')),
100 ('', 'stat', None, _('output diffstat-style summary of changes')),
101 ] + templateopts
101 ] + templateopts
102
102
103 diffopts = [
103 diffopts = [
104 ('a', 'text', None, _('treat all files as text')),
104 ('a', 'text', None, _('treat all files as text')),
105 ('g', 'git', None, _('use git extended diff format')),
105 ('g', 'git', None, _('use git extended diff format')),
106 ('', 'nodates', None, _('omit dates from diff headers'))
106 ('', 'nodates', None, _('omit dates from diff headers'))
107 ]
107 ]
108
108
109 diffwsopts = [
109 diffwsopts = [
110 ('w', 'ignore-all-space', None,
110 ('w', 'ignore-all-space', None,
111 _('ignore white space when comparing lines')),
111 _('ignore white space when comparing lines')),
112 ('b', 'ignore-space-change', None,
112 ('b', 'ignore-space-change', None,
113 _('ignore changes in the amount of white space')),
113 _('ignore changes in the amount of white space')),
114 ('B', 'ignore-blank-lines', None,
114 ('B', 'ignore-blank-lines', None,
115 _('ignore changes whose lines are all blank')),
115 _('ignore changes whose lines are all blank')),
116 ]
116 ]
117
117
118 diffopts2 = [
118 diffopts2 = [
119 ('p', 'show-function', None, _('show which function each change is in')),
119 ('p', 'show-function', None, _('show which function each change is in')),
120 ('', 'reverse', None, _('produce a diff that undoes the changes')),
120 ('', 'reverse', None, _('produce a diff that undoes the changes')),
121 ] + diffwsopts + [
121 ] + diffwsopts + [
122 ('U', 'unified', '',
122 ('U', 'unified', '',
123 _('number of lines of context to show'), _('NUM')),
123 _('number of lines of context to show'), _('NUM')),
124 ('', 'stat', None, _('output diffstat-style summary of changes')),
124 ('', 'stat', None, _('output diffstat-style summary of changes')),
125 ]
125 ]
126
126
127 mergetoolopts = [
127 mergetoolopts = [
128 ('t', 'tool', '', _('specify merge tool')),
128 ('t', 'tool', '', _('specify merge tool')),
129 ]
129 ]
130
130
131 similarityopts = [
131 similarityopts = [
132 ('s', 'similarity', '',
132 ('s', 'similarity', '',
133 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
133 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
134 ]
134 ]
135
135
136 subrepoopts = [
136 subrepoopts = [
137 ('S', 'subrepos', None,
137 ('S', 'subrepos', None,
138 _('recurse into subrepositories'))
138 _('recurse into subrepositories'))
139 ]
139 ]
140
140
141 # Commands start here, listed alphabetically
141 # Commands start here, listed alphabetically
142
142
143 @command('^add',
143 @command('^add',
144 walkopts + subrepoopts + dryrunopts,
144 walkopts + subrepoopts + dryrunopts,
145 _('[OPTION]... [FILE]...'))
145 _('[OPTION]... [FILE]...'))
146 def add(ui, repo, *pats, **opts):
146 def add(ui, repo, *pats, **opts):
147 """add the specified files on the next commit
147 """add the specified files on the next commit
148
148
149 Schedule files to be version controlled and added to the
149 Schedule files to be version controlled and added to the
150 repository.
150 repository.
151
151
152 The files will be added to the repository at the next commit. To
152 The files will be added to the repository at the next commit. To
153 undo an add before that, see :hg:`forget`.
153 undo an add before that, see :hg:`forget`.
154
154
155 If no names are given, add all files to the repository.
155 If no names are given, add all files to the repository.
156
156
157 .. container:: verbose
157 .. container:: verbose
158
158
159 An example showing how new (unknown) files are added
159 An example showing how new (unknown) files are added
160 automatically by :hg:`add`::
160 automatically by :hg:`add`::
161
161
162 $ ls
162 $ ls
163 foo.c
163 foo.c
164 $ hg status
164 $ hg status
165 ? foo.c
165 ? foo.c
166 $ hg add
166 $ hg add
167 adding foo.c
167 adding foo.c
168 $ hg status
168 $ hg status
169 A foo.c
169 A foo.c
170
170
171 Returns 0 if all files are successfully added.
171 Returns 0 if all files are successfully added.
172 """
172 """
173
173
174 m = scmutil.match(repo[None], pats, opts)
174 m = scmutil.match(repo[None], pats, opts)
175 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
175 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
176 opts.get('subrepos'), prefix="")
176 opts.get('subrepos'), prefix="")
177 return rejected and 1 or 0
177 return rejected and 1 or 0
178
178
179 @command('addremove',
179 @command('addremove',
180 similarityopts + walkopts + dryrunopts,
180 similarityopts + walkopts + dryrunopts,
181 _('[OPTION]... [FILE]...'))
181 _('[OPTION]... [FILE]...'))
182 def addremove(ui, repo, *pats, **opts):
182 def addremove(ui, repo, *pats, **opts):
183 """add all new files, delete all missing files
183 """add all new files, delete all missing files
184
184
185 Add all new files and remove all missing files from the
185 Add all new files and remove all missing files from the
186 repository.
186 repository.
187
187
188 New files are ignored if they match any of the patterns in
188 New files are ignored if they match any of the patterns in
189 ``.hgignore``. As with add, these changes take effect at the next
189 ``.hgignore``. As with add, these changes take effect at the next
190 commit.
190 commit.
191
191
192 Use the -s/--similarity option to detect renamed files. With a
192 Use the -s/--similarity option to detect renamed files. With a
193 parameter greater than 0, this compares every removed file with
193 parameter greater than 0, this compares every removed file with
194 every added file and records those similar enough as renames. This
194 every added file and records those similar enough as renames. This
195 option takes a percentage between 0 (disabled) and 100 (files must
195 option takes a percentage between 0 (disabled) and 100 (files must
196 be identical) as its parameter. Detecting renamed files this way
196 be identical) as its parameter. Detecting renamed files this way
197 can be expensive. After using this option, :hg:`status -C` can be
197 can be expensive. After using this option, :hg:`status -C` can be
198 used to check which files were identified as moved or renamed.
198 used to check which files were identified as moved or renamed.
199
199
200 Returns 0 if all files are successfully added.
200 Returns 0 if all files are successfully added.
201 """
201 """
202 try:
202 try:
203 sim = float(opts.get('similarity') or 100)
203 sim = float(opts.get('similarity') or 100)
204 except ValueError:
204 except ValueError:
205 raise util.Abort(_('similarity must be a number'))
205 raise util.Abort(_('similarity must be a number'))
206 if sim < 0 or sim > 100:
206 if sim < 0 or sim > 100:
207 raise util.Abort(_('similarity must be between 0 and 100'))
207 raise util.Abort(_('similarity must be between 0 and 100'))
208 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
208 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
209
209
210 @command('^annotate|blame',
210 @command('^annotate|blame',
211 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
211 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
212 ('', 'follow', None,
212 ('', 'follow', None,
213 _('follow copies/renames and list the filename (DEPRECATED)')),
213 _('follow copies/renames and list the filename (DEPRECATED)')),
214 ('', 'no-follow', None, _("don't follow copies and renames")),
214 ('', 'no-follow', None, _("don't follow copies and renames")),
215 ('a', 'text', None, _('treat all files as text')),
215 ('a', 'text', None, _('treat all files as text')),
216 ('u', 'user', None, _('list the author (long with -v)')),
216 ('u', 'user', None, _('list the author (long with -v)')),
217 ('f', 'file', None, _('list the filename')),
217 ('f', 'file', None, _('list the filename')),
218 ('d', 'date', None, _('list the date (short with -q)')),
218 ('d', 'date', None, _('list the date (short with -q)')),
219 ('n', 'number', None, _('list the revision number (default)')),
219 ('n', 'number', None, _('list the revision number (default)')),
220 ('c', 'changeset', None, _('list the changeset')),
220 ('c', 'changeset', None, _('list the changeset')),
221 ('l', 'line-number', None, _('show line number at the first appearance'))
221 ('l', 'line-number', None, _('show line number at the first appearance'))
222 ] + diffwsopts + walkopts,
222 ] + diffwsopts + walkopts,
223 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
223 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
224 def annotate(ui, repo, *pats, **opts):
224 def annotate(ui, repo, *pats, **opts):
225 """show changeset information by line for each file
225 """show changeset information by line for each file
226
226
227 List changes in files, showing the revision id responsible for
227 List changes in files, showing the revision id responsible for
228 each line
228 each line
229
229
230 This command is useful for discovering when a change was made and
230 This command is useful for discovering when a change was made and
231 by whom.
231 by whom.
232
232
233 Without the -a/--text option, annotate will avoid processing files
233 Without the -a/--text option, annotate will avoid processing files
234 it detects as binary. With -a, annotate will annotate the file
234 it detects as binary. With -a, annotate will annotate the file
235 anyway, although the results will probably be neither useful
235 anyway, although the results will probably be neither useful
236 nor desirable.
236 nor desirable.
237
237
238 Returns 0 on success.
238 Returns 0 on success.
239 """
239 """
240 if opts.get('follow'):
240 if opts.get('follow'):
241 # --follow is deprecated and now just an alias for -f/--file
241 # --follow is deprecated and now just an alias for -f/--file
242 # to mimic the behavior of Mercurial before version 1.5
242 # to mimic the behavior of Mercurial before version 1.5
243 opts['file'] = True
243 opts['file'] = True
244
244
245 datefunc = ui.quiet and util.shortdate or util.datestr
245 datefunc = ui.quiet and util.shortdate or util.datestr
246 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
246 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
247
247
248 if not pats:
248 if not pats:
249 raise util.Abort(_('at least one filename or pattern is required'))
249 raise util.Abort(_('at least one filename or pattern is required'))
250
250
251 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
251 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
252 ('number', ' ', lambda x: str(x[0].rev())),
252 ('number', ' ', lambda x: str(x[0].rev())),
253 ('changeset', ' ', lambda x: short(x[0].node())),
253 ('changeset', ' ', lambda x: short(x[0].node())),
254 ('date', ' ', getdate),
254 ('date', ' ', getdate),
255 ('file', ' ', lambda x: x[0].path()),
255 ('file', ' ', lambda x: x[0].path()),
256 ('line_number', ':', lambda x: str(x[1])),
256 ('line_number', ':', lambda x: str(x[1])),
257 ]
257 ]
258
258
259 if (not opts.get('user') and not opts.get('changeset')
259 if (not opts.get('user') and not opts.get('changeset')
260 and not opts.get('date') and not opts.get('file')):
260 and not opts.get('date') and not opts.get('file')):
261 opts['number'] = True
261 opts['number'] = True
262
262
263 linenumber = opts.get('line_number') is not None
263 linenumber = opts.get('line_number') is not None
264 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
264 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
265 raise util.Abort(_('at least one of -n/-c is required for -l'))
265 raise util.Abort(_('at least one of -n/-c is required for -l'))
266
266
267 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
267 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
268 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
268 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
269
269
270 def bad(x, y):
270 def bad(x, y):
271 raise util.Abort("%s: %s" % (x, y))
271 raise util.Abort("%s: %s" % (x, y))
272
272
273 ctx = scmutil.revsingle(repo, opts.get('rev'))
273 ctx = scmutil.revsingle(repo, opts.get('rev'))
274 m = scmutil.match(ctx, pats, opts)
274 m = scmutil.match(ctx, pats, opts)
275 m.bad = bad
275 m.bad = bad
276 follow = not opts.get('no_follow')
276 follow = not opts.get('no_follow')
277 diffopts = patch.diffopts(ui, opts, section='annotate')
277 diffopts = patch.diffopts(ui, opts, section='annotate')
278 for abs in ctx.walk(m):
278 for abs in ctx.walk(m):
279 fctx = ctx[abs]
279 fctx = ctx[abs]
280 if not opts.get('text') and util.binary(fctx.data()):
280 if not opts.get('text') and util.binary(fctx.data()):
281 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
281 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
282 continue
282 continue
283
283
284 lines = fctx.annotate(follow=follow, linenumber=linenumber,
284 lines = fctx.annotate(follow=follow, linenumber=linenumber,
285 diffopts=diffopts)
285 diffopts=diffopts)
286 pieces = []
286 pieces = []
287
287
288 for f, sep in funcmap:
288 for f, sep in funcmap:
289 l = [f(n) for n, dummy in lines]
289 l = [f(n) for n, dummy in lines]
290 if l:
290 if l:
291 sized = [(x, encoding.colwidth(x)) for x in l]
291 sized = [(x, encoding.colwidth(x)) for x in l]
292 ml = max([w for x, w in sized])
292 ml = max([w for x, w in sized])
293 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
293 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
294 for x, w in sized])
294 for x, w in sized])
295
295
296 if pieces:
296 if pieces:
297 for p, l in zip(zip(*pieces), lines):
297 for p, l in zip(zip(*pieces), lines):
298 ui.write("%s: %s" % ("".join(p), l[1]))
298 ui.write("%s: %s" % ("".join(p), l[1]))
299
299
300 @command('archive',
300 @command('archive',
301 [('', 'no-decode', None, _('do not pass files through decoders')),
301 [('', 'no-decode', None, _('do not pass files through decoders')),
302 ('p', 'prefix', '', _('directory prefix for files in archive'),
302 ('p', 'prefix', '', _('directory prefix for files in archive'),
303 _('PREFIX')),
303 _('PREFIX')),
304 ('r', 'rev', '', _('revision to distribute'), _('REV')),
304 ('r', 'rev', '', _('revision to distribute'), _('REV')),
305 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
305 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
306 ] + subrepoopts + walkopts,
306 ] + subrepoopts + walkopts,
307 _('[OPTION]... DEST'))
307 _('[OPTION]... DEST'))
308 def archive(ui, repo, dest, **opts):
308 def archive(ui, repo, dest, **opts):
309 '''create an unversioned archive of a repository revision
309 '''create an unversioned archive of a repository revision
310
310
311 By default, the revision used is the parent of the working
311 By default, the revision used is the parent of the working
312 directory; use -r/--rev to specify a different revision.
312 directory; use -r/--rev to specify a different revision.
313
313
314 The archive type is automatically detected based on file
314 The archive type is automatically detected based on file
315 extension (or override using -t/--type).
315 extension (or override using -t/--type).
316
316
317 .. container:: verbose
317 .. container:: verbose
318
318
319 Examples:
319 Examples:
320
320
321 - create a zip file containing the 1.0 release::
321 - create a zip file containing the 1.0 release::
322
322
323 hg archive -r 1.0 project-1.0.zip
323 hg archive -r 1.0 project-1.0.zip
324
324
325 - create a tarball excluding .hg files::
325 - create a tarball excluding .hg files::
326
326
327 hg archive project.tar.gz -X ".hg*"
327 hg archive project.tar.gz -X ".hg*"
328
328
329 Valid types are:
329 Valid types are:
330
330
331 :``files``: a directory full of files (default)
331 :``files``: a directory full of files (default)
332 :``tar``: tar archive, uncompressed
332 :``tar``: tar archive, uncompressed
333 :``tbz2``: tar archive, compressed using bzip2
333 :``tbz2``: tar archive, compressed using bzip2
334 :``tgz``: tar archive, compressed using gzip
334 :``tgz``: tar archive, compressed using gzip
335 :``uzip``: zip archive, uncompressed
335 :``uzip``: zip archive, uncompressed
336 :``zip``: zip archive, compressed using deflate
336 :``zip``: zip archive, compressed using deflate
337
337
338 The exact name of the destination archive or directory is given
338 The exact name of the destination archive or directory is given
339 using a format string; see :hg:`help export` for details.
339 using a format string; see :hg:`help export` for details.
340
340
341 Each member added to an archive file has a directory prefix
341 Each member added to an archive file has a directory prefix
342 prepended. Use -p/--prefix to specify a format string for the
342 prepended. Use -p/--prefix to specify a format string for the
343 prefix. The default is the basename of the archive, with suffixes
343 prefix. The default is the basename of the archive, with suffixes
344 removed.
344 removed.
345
345
346 Returns 0 on success.
346 Returns 0 on success.
347 '''
347 '''
348
348
349 ctx = scmutil.revsingle(repo, opts.get('rev'))
349 ctx = scmutil.revsingle(repo, opts.get('rev'))
350 if not ctx:
350 if not ctx:
351 raise util.Abort(_('no working directory: please specify a revision'))
351 raise util.Abort(_('no working directory: please specify a revision'))
352 node = ctx.node()
352 node = ctx.node()
353 dest = cmdutil.makefilename(repo, dest, node)
353 dest = cmdutil.makefilename(repo, dest, node)
354 if os.path.realpath(dest) == repo.root:
354 if os.path.realpath(dest) == repo.root:
355 raise util.Abort(_('repository root cannot be destination'))
355 raise util.Abort(_('repository root cannot be destination'))
356
356
357 kind = opts.get('type') or archival.guesskind(dest) or 'files'
357 kind = opts.get('type') or archival.guesskind(dest) or 'files'
358 prefix = opts.get('prefix')
358 prefix = opts.get('prefix')
359
359
360 if dest == '-':
360 if dest == '-':
361 if kind == 'files':
361 if kind == 'files':
362 raise util.Abort(_('cannot archive plain files to stdout'))
362 raise util.Abort(_('cannot archive plain files to stdout'))
363 dest = cmdutil.makefileobj(repo, dest)
363 dest = cmdutil.makefileobj(repo, dest)
364 if not prefix:
364 if not prefix:
365 prefix = os.path.basename(repo.root) + '-%h'
365 prefix = os.path.basename(repo.root) + '-%h'
366
366
367 prefix = cmdutil.makefilename(repo, prefix, node)
367 prefix = cmdutil.makefilename(repo, prefix, node)
368 matchfn = scmutil.match(ctx, [], opts)
368 matchfn = scmutil.match(ctx, [], opts)
369 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
369 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
370 matchfn, prefix, subrepos=opts.get('subrepos'))
370 matchfn, prefix, subrepos=opts.get('subrepos'))
371
371
372 @command('backout',
372 @command('backout',
373 [('', 'merge', None, _('merge with old dirstate parent after backout')),
373 [('', 'merge', None, _('merge with old dirstate parent after backout')),
374 ('', 'parent', '',
374 ('', 'parent', '',
375 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
375 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
376 ('r', 'rev', '', _('revision to backout'), _('REV')),
376 ('r', 'rev', '', _('revision to backout'), _('REV')),
377 ] + mergetoolopts + walkopts + commitopts + commitopts2,
377 ] + mergetoolopts + walkopts + commitopts + commitopts2,
378 _('[OPTION]... [-r] REV'))
378 _('[OPTION]... [-r] REV'))
379 def backout(ui, repo, node=None, rev=None, **opts):
379 def backout(ui, repo, node=None, rev=None, **opts):
380 '''reverse effect of earlier changeset
380 '''reverse effect of earlier changeset
381
381
382 Prepare a new changeset with the effect of REV undone in the
382 Prepare a new changeset with the effect of REV undone in the
383 current working directory.
383 current working directory.
384
384
385 If REV is the parent of the working directory, then this new changeset
385 If REV is the parent of the working directory, then this new changeset
386 is committed automatically. Otherwise, hg needs to merge the
386 is committed automatically. Otherwise, hg needs to merge the
387 changes and the merged result is left uncommitted.
387 changes and the merged result is left uncommitted.
388
388
389 .. note::
389 .. note::
390 backout cannot be used to fix either an unwanted or
390 backout cannot be used to fix either an unwanted or
391 incorrect merge.
391 incorrect merge.
392
392
393 .. container:: verbose
393 .. container:: verbose
394
394
395 By default, the pending changeset will have one parent,
395 By default, the pending changeset will have one parent,
396 maintaining a linear history. With --merge, the pending
396 maintaining a linear history. With --merge, the pending
397 changeset will instead have two parents: the old parent of the
397 changeset will instead have two parents: the old parent of the
398 working directory and a new child of REV that simply undoes REV.
398 working directory and a new child of REV that simply undoes REV.
399
399
400 Before version 1.7, the behavior without --merge was equivalent
400 Before version 1.7, the behavior without --merge was equivalent
401 to specifying --merge followed by :hg:`update --clean .` to
401 to specifying --merge followed by :hg:`update --clean .` to
402 cancel the merge and leave the child of REV as a head to be
402 cancel the merge and leave the child of REV as a head to be
403 merged separately.
403 merged separately.
404
404
405 See :hg:`help dates` for a list of formats valid for -d/--date.
405 See :hg:`help dates` for a list of formats valid for -d/--date.
406
406
407 Returns 0 on success.
407 Returns 0 on success.
408 '''
408 '''
409 if rev and node:
409 if rev and node:
410 raise util.Abort(_("please specify just one revision"))
410 raise util.Abort(_("please specify just one revision"))
411
411
412 if not rev:
412 if not rev:
413 rev = node
413 rev = node
414
414
415 if not rev:
415 if not rev:
416 raise util.Abort(_("please specify a revision to backout"))
416 raise util.Abort(_("please specify a revision to backout"))
417
417
418 date = opts.get('date')
418 date = opts.get('date')
419 if date:
419 if date:
420 opts['date'] = util.parsedate(date)
420 opts['date'] = util.parsedate(date)
421
421
422 cmdutil.bailifchanged(repo)
422 cmdutil.bailifchanged(repo)
423 node = scmutil.revsingle(repo, rev).node()
423 node = scmutil.revsingle(repo, rev).node()
424
424
425 op1, op2 = repo.dirstate.parents()
425 op1, op2 = repo.dirstate.parents()
426 a = repo.changelog.ancestor(op1, node)
426 a = repo.changelog.ancestor(op1, node)
427 if a != node:
427 if a != node:
428 raise util.Abort(_('cannot backout change on a different branch'))
428 raise util.Abort(_('cannot backout change on a different branch'))
429
429
430 p1, p2 = repo.changelog.parents(node)
430 p1, p2 = repo.changelog.parents(node)
431 if p1 == nullid:
431 if p1 == nullid:
432 raise util.Abort(_('cannot backout a change with no parents'))
432 raise util.Abort(_('cannot backout a change with no parents'))
433 if p2 != nullid:
433 if p2 != nullid:
434 if not opts.get('parent'):
434 if not opts.get('parent'):
435 raise util.Abort(_('cannot backout a merge changeset'))
435 raise util.Abort(_('cannot backout a merge changeset'))
436 p = repo.lookup(opts['parent'])
436 p = repo.lookup(opts['parent'])
437 if p not in (p1, p2):
437 if p not in (p1, p2):
438 raise util.Abort(_('%s is not a parent of %s') %
438 raise util.Abort(_('%s is not a parent of %s') %
439 (short(p), short(node)))
439 (short(p), short(node)))
440 parent = p
440 parent = p
441 else:
441 else:
442 if opts.get('parent'):
442 if opts.get('parent'):
443 raise util.Abort(_('cannot use --parent on non-merge changeset'))
443 raise util.Abort(_('cannot use --parent on non-merge changeset'))
444 parent = p1
444 parent = p1
445
445
446 # the backout should appear on the same branch
446 # the backout should appear on the same branch
447 branch = repo.dirstate.branch()
447 branch = repo.dirstate.branch()
448 hg.clean(repo, node, show_stats=False)
448 hg.clean(repo, node, show_stats=False)
449 repo.dirstate.setbranch(branch)
449 repo.dirstate.setbranch(branch)
450 revert_opts = opts.copy()
450 revert_opts = opts.copy()
451 revert_opts['date'] = None
451 revert_opts['date'] = None
452 revert_opts['all'] = True
452 revert_opts['all'] = True
453 revert_opts['rev'] = hex(parent)
453 revert_opts['rev'] = hex(parent)
454 revert_opts['no_backup'] = None
454 revert_opts['no_backup'] = None
455 revert(ui, repo, **revert_opts)
455 revert(ui, repo, **revert_opts)
456 if not opts.get('merge') and op1 != node:
456 if not opts.get('merge') and op1 != node:
457 try:
457 try:
458 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
458 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
459 return hg.update(repo, op1)
459 return hg.update(repo, op1)
460 finally:
460 finally:
461 ui.setconfig('ui', 'forcemerge', '')
461 ui.setconfig('ui', 'forcemerge', '')
462
462
463 commit_opts = opts.copy()
463 commit_opts = opts.copy()
464 commit_opts['addremove'] = False
464 commit_opts['addremove'] = False
465 if not commit_opts['message'] and not commit_opts['logfile']:
465 if not commit_opts['message'] and not commit_opts['logfile']:
466 # we don't translate commit messages
466 # we don't translate commit messages
467 commit_opts['message'] = "Backed out changeset %s" % short(node)
467 commit_opts['message'] = "Backed out changeset %s" % short(node)
468 commit_opts['force_editor'] = True
468 commit_opts['force_editor'] = True
469 commit(ui, repo, **commit_opts)
469 commit(ui, repo, **commit_opts)
470 def nice(node):
470 def nice(node):
471 return '%d:%s' % (repo.changelog.rev(node), short(node))
471 return '%d:%s' % (repo.changelog.rev(node), short(node))
472 ui.status(_('changeset %s backs out changeset %s\n') %
472 ui.status(_('changeset %s backs out changeset %s\n') %
473 (nice(repo.changelog.tip()), nice(node)))
473 (nice(repo.changelog.tip()), nice(node)))
474 if opts.get('merge') and op1 != node:
474 if opts.get('merge') and op1 != node:
475 hg.clean(repo, op1, show_stats=False)
475 hg.clean(repo, op1, show_stats=False)
476 ui.status(_('merging with changeset %s\n')
476 ui.status(_('merging with changeset %s\n')
477 % nice(repo.changelog.tip()))
477 % nice(repo.changelog.tip()))
478 try:
478 try:
479 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
479 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
480 return hg.merge(repo, hex(repo.changelog.tip()))
480 return hg.merge(repo, hex(repo.changelog.tip()))
481 finally:
481 finally:
482 ui.setconfig('ui', 'forcemerge', '')
482 ui.setconfig('ui', 'forcemerge', '')
483 return 0
483 return 0
484
484
485 @command('bisect',
485 @command('bisect',
486 [('r', 'reset', False, _('reset bisect state')),
486 [('r', 'reset', False, _('reset bisect state')),
487 ('g', 'good', False, _('mark changeset good')),
487 ('g', 'good', False, _('mark changeset good')),
488 ('b', 'bad', False, _('mark changeset bad')),
488 ('b', 'bad', False, _('mark changeset bad')),
489 ('s', 'skip', False, _('skip testing changeset')),
489 ('s', 'skip', False, _('skip testing changeset')),
490 ('e', 'extend', False, _('extend the bisect range')),
490 ('e', 'extend', False, _('extend the bisect range')),
491 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
491 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
492 ('U', 'noupdate', False, _('do not update to target'))],
492 ('U', 'noupdate', False, _('do not update to target'))],
493 _("[-gbsr] [-U] [-c CMD] [REV]"))
493 _("[-gbsr] [-U] [-c CMD] [REV]"))
494 def bisect(ui, repo, rev=None, extra=None, command=None,
494 def bisect(ui, repo, rev=None, extra=None, command=None,
495 reset=None, good=None, bad=None, skip=None, extend=None,
495 reset=None, good=None, bad=None, skip=None, extend=None,
496 noupdate=None):
496 noupdate=None):
497 """subdivision search of changesets
497 """subdivision search of changesets
498
498
499 This command helps to find changesets which introduce problems. To
499 This command helps to find changesets which introduce problems. To
500 use, mark the earliest changeset you know exhibits the problem as
500 use, mark the earliest changeset you know exhibits the problem as
501 bad, then mark the latest changeset which is free from the problem
501 bad, then mark the latest changeset which is free from the problem
502 as good. Bisect will update your working directory to a revision
502 as good. Bisect will update your working directory to a revision
503 for testing (unless the -U/--noupdate option is specified). Once
503 for testing (unless the -U/--noupdate option is specified). Once
504 you have performed tests, mark the working directory as good or
504 you have performed tests, mark the working directory as good or
505 bad, and bisect will either update to another candidate changeset
505 bad, and bisect will either update to another candidate changeset
506 or announce that it has found the bad revision.
506 or announce that it has found the bad revision.
507
507
508 As a shortcut, you can also use the revision argument to mark a
508 As a shortcut, you can also use the revision argument to mark a
509 revision as good or bad without checking it out first.
509 revision as good or bad without checking it out first.
510
510
511 If you supply a command, it will be used for automatic bisection.
511 If you supply a command, it will be used for automatic bisection.
512 Its exit status will be used to mark revisions as good or bad:
512 Its exit status will be used to mark revisions as good or bad:
513 status 0 means good, 125 means to skip the revision, 127
513 status 0 means good, 125 means to skip the revision, 127
514 (command not found) will abort the bisection, and any other
514 (command not found) will abort the bisection, and any other
515 non-zero exit status means the revision is bad.
515 non-zero exit status means the revision is bad.
516
516
517 .. container:: verbose
517 .. container:: verbose
518
518
519 Some examples:
519 Some examples:
520
520
521 - start a bisection with known bad revision 12, and good revision 34::
521 - start a bisection with known bad revision 12, and good revision 34::
522
522
523 hg bisect --bad 34
523 hg bisect --bad 34
524 hg bisect --good 12
524 hg bisect --good 12
525
525
526 - advance the current bisection by marking current revision as good or
526 - advance the current bisection by marking current revision as good or
527 bad::
527 bad::
528
528
529 hg bisect --good
529 hg bisect --good
530 hg bisect --bad
530 hg bisect --bad
531
531
532 - mark the current revision, or a known revision, to be skipped (eg. if
532 - mark the current revision, or a known revision, to be skipped (eg. if
533 that revision is not usable because of another issue)::
533 that revision is not usable because of another issue)::
534
534
535 hg bisect --skip
535 hg bisect --skip
536 hg bisect --skip 23
536 hg bisect --skip 23
537
537
538 - forget the current bisection::
538 - forget the current bisection::
539
539
540 hg bisect --reset
540 hg bisect --reset
541
541
542 - use 'make && make tests' to automatically find the first broken
542 - use 'make && make tests' to automatically find the first broken
543 revision::
543 revision::
544
544
545 hg bisect --reset
545 hg bisect --reset
546 hg bisect --bad 34
546 hg bisect --bad 34
547 hg bisect --good 12
547 hg bisect --good 12
548 hg bisect --command 'make && make tests'
548 hg bisect --command 'make && make tests'
549
549
550 - see all changesets whose states are already known in the current
550 - see all changesets whose states are already known in the current
551 bisection::
551 bisection::
552
552
553 hg log -r "bisect(pruned)"
553 hg log -r "bisect(pruned)"
554
554
555 - see all changesets that took part in the current bisection::
555 - see all changesets that took part in the current bisection::
556
556
557 hg log -r "bisect(range)"
557 hg log -r "bisect(range)"
558
558
559 - with the graphlog extension, you can even get a nice graph::
559 - with the graphlog extension, you can even get a nice graph::
560
560
561 hg log --graph -r "bisect(range)"
561 hg log --graph -r "bisect(range)"
562
562
563 See :hg:`help revsets` for more about the `bisect()` keyword.
563 See :hg:`help revsets` for more about the `bisect()` keyword.
564
564
565 Returns 0 on success.
565 Returns 0 on success.
566 """
566 """
567 def extendbisectrange(nodes, good):
567 def extendbisectrange(nodes, good):
568 # bisect is incomplete when it ends on a merge node and
568 # bisect is incomplete when it ends on a merge node and
569 # one of the parent was not checked.
569 # one of the parent was not checked.
570 parents = repo[nodes[0]].parents()
570 parents = repo[nodes[0]].parents()
571 if len(parents) > 1:
571 if len(parents) > 1:
572 side = good and state['bad'] or state['good']
572 side = good and state['bad'] or state['good']
573 num = len(set(i.node() for i in parents) & set(side))
573 num = len(set(i.node() for i in parents) & set(side))
574 if num == 1:
574 if num == 1:
575 return parents[0].ancestor(parents[1])
575 return parents[0].ancestor(parents[1])
576 return None
576 return None
577
577
578 def print_result(nodes, good):
578 def print_result(nodes, good):
579 displayer = cmdutil.show_changeset(ui, repo, {})
579 displayer = cmdutil.show_changeset(ui, repo, {})
580 if len(nodes) == 1:
580 if len(nodes) == 1:
581 # narrowed it down to a single revision
581 # narrowed it down to a single revision
582 if good:
582 if good:
583 ui.write(_("The first good revision is:\n"))
583 ui.write(_("The first good revision is:\n"))
584 else:
584 else:
585 ui.write(_("The first bad revision is:\n"))
585 ui.write(_("The first bad revision is:\n"))
586 displayer.show(repo[nodes[0]])
586 displayer.show(repo[nodes[0]])
587 extendnode = extendbisectrange(nodes, good)
587 extendnode = extendbisectrange(nodes, good)
588 if extendnode is not None:
588 if extendnode is not None:
589 ui.write(_('Not all ancestors of this changeset have been'
589 ui.write(_('Not all ancestors of this changeset have been'
590 ' checked.\nUse bisect --extend to continue the '
590 ' checked.\nUse bisect --extend to continue the '
591 'bisection from\nthe common ancestor, %s.\n')
591 'bisection from\nthe common ancestor, %s.\n')
592 % extendnode)
592 % extendnode)
593 else:
593 else:
594 # multiple possible revisions
594 # multiple possible revisions
595 if good:
595 if good:
596 ui.write(_("Due to skipped revisions, the first "
596 ui.write(_("Due to skipped revisions, the first "
597 "good revision could be any of:\n"))
597 "good revision could be any of:\n"))
598 else:
598 else:
599 ui.write(_("Due to skipped revisions, the first "
599 ui.write(_("Due to skipped revisions, the first "
600 "bad revision could be any of:\n"))
600 "bad revision could be any of:\n"))
601 for n in nodes:
601 for n in nodes:
602 displayer.show(repo[n])
602 displayer.show(repo[n])
603 displayer.close()
603 displayer.close()
604
604
605 def check_state(state, interactive=True):
605 def check_state(state, interactive=True):
606 if not state['good'] or not state['bad']:
606 if not state['good'] or not state['bad']:
607 if (good or bad or skip or reset) and interactive:
607 if (good or bad or skip or reset) and interactive:
608 return
608 return
609 if not state['good']:
609 if not state['good']:
610 raise util.Abort(_('cannot bisect (no known good revisions)'))
610 raise util.Abort(_('cannot bisect (no known good revisions)'))
611 else:
611 else:
612 raise util.Abort(_('cannot bisect (no known bad revisions)'))
612 raise util.Abort(_('cannot bisect (no known bad revisions)'))
613 return True
613 return True
614
614
615 # backward compatibility
615 # backward compatibility
616 if rev in "good bad reset init".split():
616 if rev in "good bad reset init".split():
617 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
617 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
618 cmd, rev, extra = rev, extra, None
618 cmd, rev, extra = rev, extra, None
619 if cmd == "good":
619 if cmd == "good":
620 good = True
620 good = True
621 elif cmd == "bad":
621 elif cmd == "bad":
622 bad = True
622 bad = True
623 else:
623 else:
624 reset = True
624 reset = True
625 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
625 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
626 raise util.Abort(_('incompatible arguments'))
626 raise util.Abort(_('incompatible arguments'))
627
627
628 if reset:
628 if reset:
629 p = repo.join("bisect.state")
629 p = repo.join("bisect.state")
630 if os.path.exists(p):
630 if os.path.exists(p):
631 os.unlink(p)
631 os.unlink(p)
632 return
632 return
633
633
634 state = hbisect.load_state(repo)
634 state = hbisect.load_state(repo)
635
635
636 if command:
636 if command:
637 changesets = 1
637 changesets = 1
638 try:
638 try:
639 while changesets:
639 while changesets:
640 # update state
640 # update state
641 status = util.system(command, out=ui.fout)
641 status = util.system(command, out=ui.fout)
642 if status == 125:
642 if status == 125:
643 transition = "skip"
643 transition = "skip"
644 elif status == 0:
644 elif status == 0:
645 transition = "good"
645 transition = "good"
646 # status < 0 means process was killed
646 # status < 0 means process was killed
647 elif status == 127:
647 elif status == 127:
648 raise util.Abort(_("failed to execute %s") % command)
648 raise util.Abort(_("failed to execute %s") % command)
649 elif status < 0:
649 elif status < 0:
650 raise util.Abort(_("%s killed") % command)
650 raise util.Abort(_("%s killed") % command)
651 else:
651 else:
652 transition = "bad"
652 transition = "bad"
653 ctx = scmutil.revsingle(repo, rev)
653 ctx = scmutil.revsingle(repo, rev)
654 rev = None # clear for future iterations
654 rev = None # clear for future iterations
655 state[transition].append(ctx.node())
655 state[transition].append(ctx.node())
656 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
656 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
657 check_state(state, interactive=False)
657 check_state(state, interactive=False)
658 # bisect
658 # bisect
659 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
659 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
660 # update to next check
660 # update to next check
661 cmdutil.bailifchanged(repo)
661 cmdutil.bailifchanged(repo)
662 hg.clean(repo, nodes[0], show_stats=False)
662 hg.clean(repo, nodes[0], show_stats=False)
663 finally:
663 finally:
664 hbisect.save_state(repo, state)
664 hbisect.save_state(repo, state)
665 print_result(nodes, good)
665 print_result(nodes, good)
666 return
666 return
667
667
668 # update state
668 # update state
669
669
670 if rev:
670 if rev:
671 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
671 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
672 else:
672 else:
673 nodes = [repo.lookup('.')]
673 nodes = [repo.lookup('.')]
674
674
675 if good or bad or skip:
675 if good or bad or skip:
676 if good:
676 if good:
677 state['good'] += nodes
677 state['good'] += nodes
678 elif bad:
678 elif bad:
679 state['bad'] += nodes
679 state['bad'] += nodes
680 elif skip:
680 elif skip:
681 state['skip'] += nodes
681 state['skip'] += nodes
682 hbisect.save_state(repo, state)
682 hbisect.save_state(repo, state)
683
683
684 if not check_state(state):
684 if not check_state(state):
685 return
685 return
686
686
687 # actually bisect
687 # actually bisect
688 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
688 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
689 if extend:
689 if extend:
690 if not changesets:
690 if not changesets:
691 extendnode = extendbisectrange(nodes, good)
691 extendnode = extendbisectrange(nodes, good)
692 if extendnode is not None:
692 if extendnode is not None:
693 ui.write(_("Extending search to changeset %d:%s\n"
693 ui.write(_("Extending search to changeset %d:%s\n"
694 % (extendnode.rev(), extendnode)))
694 % (extendnode.rev(), extendnode)))
695 if noupdate:
695 if noupdate:
696 return
696 return
697 cmdutil.bailifchanged(repo)
697 cmdutil.bailifchanged(repo)
698 return hg.clean(repo, extendnode.node())
698 return hg.clean(repo, extendnode.node())
699 raise util.Abort(_("nothing to extend"))
699 raise util.Abort(_("nothing to extend"))
700
700
701 if changesets == 0:
701 if changesets == 0:
702 print_result(nodes, good)
702 print_result(nodes, good)
703 else:
703 else:
704 assert len(nodes) == 1 # only a single node can be tested next
704 assert len(nodes) == 1 # only a single node can be tested next
705 node = nodes[0]
705 node = nodes[0]
706 # compute the approximate number of remaining tests
706 # compute the approximate number of remaining tests
707 tests, size = 0, 2
707 tests, size = 0, 2
708 while size <= changesets:
708 while size <= changesets:
709 tests, size = tests + 1, size * 2
709 tests, size = tests + 1, size * 2
710 rev = repo.changelog.rev(node)
710 rev = repo.changelog.rev(node)
711 ui.write(_("Testing changeset %d:%s "
711 ui.write(_("Testing changeset %d:%s "
712 "(%d changesets remaining, ~%d tests)\n")
712 "(%d changesets remaining, ~%d tests)\n")
713 % (rev, short(node), changesets, tests))
713 % (rev, short(node), changesets, tests))
714 if not noupdate:
714 if not noupdate:
715 cmdutil.bailifchanged(repo)
715 cmdutil.bailifchanged(repo)
716 return hg.clean(repo, node)
716 return hg.clean(repo, node)
717
717
718 @command('bookmarks',
718 @command('bookmarks',
719 [('f', 'force', False, _('force')),
719 [('f', 'force', False, _('force')),
720 ('r', 'rev', '', _('revision'), _('REV')),
720 ('r', 'rev', '', _('revision'), _('REV')),
721 ('d', 'delete', False, _('delete a given bookmark')),
721 ('d', 'delete', False, _('delete a given bookmark')),
722 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
722 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
723 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
723 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
724 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]'))
724 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]'))
725 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
725 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
726 rename=None, inactive=False):
726 rename=None, inactive=False):
727 '''track a line of development with movable markers
727 '''track a line of development with movable markers
728
728
729 Bookmarks are pointers to certain commits that move when committing.
729 Bookmarks are pointers to certain commits that move when committing.
730 Bookmarks are local. They can be renamed, copied and deleted. It is
730 Bookmarks are local. They can be renamed, copied and deleted. It is
731 possible to use :hg:`merge NAME` to merge from a given bookmark, and
731 possible to use :hg:`merge NAME` to merge from a given bookmark, and
732 :hg:`update NAME` to update to a given bookmark.
732 :hg:`update NAME` to update to a given bookmark.
733
733
734 You can use :hg:`bookmark NAME` to set a bookmark on the working
734 You can use :hg:`bookmark NAME` to set a bookmark on the working
735 directory's parent revision with the given name. If you specify
735 directory's parent revision with the given name. If you specify
736 a revision using -r REV (where REV may be an existing bookmark),
736 a revision using -r REV (where REV may be an existing bookmark),
737 the bookmark is assigned to that revision.
737 the bookmark is assigned to that revision.
738
738
739 Bookmarks can be pushed and pulled between repositories (see :hg:`help
739 Bookmarks can be pushed and pulled between repositories (see :hg:`help
740 push` and :hg:`help pull`). This requires both the local and remote
740 push` and :hg:`help pull`). This requires both the local and remote
741 repositories to support bookmarks. For versions prior to 1.8, this means
741 repositories to support bookmarks. For versions prior to 1.8, this means
742 the bookmarks extension must be enabled.
742 the bookmarks extension must be enabled.
743 '''
743 '''
744 hexfn = ui.debugflag and hex or short
744 hexfn = ui.debugflag and hex or short
745 marks = repo._bookmarks
745 marks = repo._bookmarks
746 cur = repo.changectx('.').node()
746 cur = repo.changectx('.').node()
747
747
748 if delete:
748 if delete:
749 if mark is None:
749 if mark is None:
750 raise util.Abort(_("bookmark name required"))
750 raise util.Abort(_("bookmark name required"))
751 if mark not in marks:
751 if mark not in marks:
752 raise util.Abort(_("bookmark '%s' does not exist") % mark)
752 raise util.Abort(_("bookmark '%s' does not exist") % mark)
753 if mark == repo._bookmarkcurrent:
753 if mark == repo._bookmarkcurrent:
754 bookmarks.setcurrent(repo, None)
754 bookmarks.setcurrent(repo, None)
755 del marks[mark]
755 del marks[mark]
756 bookmarks.write(repo)
756 bookmarks.write(repo)
757 return
757 return
758
758
759 if rename:
759 if rename:
760 if rename not in marks:
760 if rename not in marks:
761 raise util.Abort(_("bookmark '%s' does not exist") % rename)
761 raise util.Abort(_("bookmark '%s' does not exist") % rename)
762 if mark in marks and not force:
762 if mark in marks and not force:
763 raise util.Abort(_("bookmark '%s' already exists "
763 raise util.Abort(_("bookmark '%s' already exists "
764 "(use -f to force)") % mark)
764 "(use -f to force)") % mark)
765 if mark is None:
765 if mark is None:
766 raise util.Abort(_("new bookmark name required"))
766 raise util.Abort(_("new bookmark name required"))
767 marks[mark] = marks[rename]
767 marks[mark] = marks[rename]
768 if repo._bookmarkcurrent == rename and not inactive:
768 if repo._bookmarkcurrent == rename and not inactive:
769 bookmarks.setcurrent(repo, mark)
769 bookmarks.setcurrent(repo, mark)
770 del marks[rename]
770 del marks[rename]
771 bookmarks.write(repo)
771 bookmarks.write(repo)
772 return
772 return
773
773
774 if mark is not None:
774 if mark is not None:
775 if "\n" in mark:
775 if "\n" in mark:
776 raise util.Abort(_("bookmark name cannot contain newlines"))
776 raise util.Abort(_("bookmark name cannot contain newlines"))
777 mark = mark.strip()
777 mark = mark.strip()
778 if not mark:
778 if not mark:
779 raise util.Abort(_("bookmark names cannot consist entirely of "
779 raise util.Abort(_("bookmark names cannot consist entirely of "
780 "whitespace"))
780 "whitespace"))
781 if inactive and mark == repo._bookmarkcurrent:
781 if inactive and mark == repo._bookmarkcurrent:
782 bookmarks.setcurrent(repo, None)
782 bookmarks.setcurrent(repo, None)
783 return
783 return
784 if mark in marks and not force:
784 if mark in marks and not force:
785 raise util.Abort(_("bookmark '%s' already exists "
785 raise util.Abort(_("bookmark '%s' already exists "
786 "(use -f to force)") % mark)
786 "(use -f to force)") % mark)
787 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
787 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
788 and not force):
788 and not force):
789 raise util.Abort(
789 raise util.Abort(
790 _("a bookmark cannot have the name of an existing branch"))
790 _("a bookmark cannot have the name of an existing branch"))
791 if rev:
791 if rev:
792 marks[mark] = repo.lookup(rev)
792 marks[mark] = repo.lookup(rev)
793 else:
793 else:
794 marks[mark] = cur
794 marks[mark] = cur
795 if not inactive and cur == marks[mark]:
795 if not inactive and cur == marks[mark]:
796 bookmarks.setcurrent(repo, mark)
796 bookmarks.setcurrent(repo, mark)
797 bookmarks.write(repo)
797 bookmarks.write(repo)
798 return
798 return
799
799
800 if mark is None:
800 if mark is None:
801 if rev:
801 if rev:
802 raise util.Abort(_("bookmark name required"))
802 raise util.Abort(_("bookmark name required"))
803 if len(marks) == 0:
803 if len(marks) == 0:
804 ui.status(_("no bookmarks set\n"))
804 ui.status(_("no bookmarks set\n"))
805 else:
805 else:
806 for bmark, n in sorted(marks.iteritems()):
806 for bmark, n in sorted(marks.iteritems()):
807 current = repo._bookmarkcurrent
807 current = repo._bookmarkcurrent
808 if bmark == current and n == cur:
808 if bmark == current and n == cur:
809 prefix, label = '*', 'bookmarks.current'
809 prefix, label = '*', 'bookmarks.current'
810 else:
810 else:
811 prefix, label = ' ', ''
811 prefix, label = ' ', ''
812
812
813 if ui.quiet:
813 if ui.quiet:
814 ui.write("%s\n" % bmark, label=label)
814 ui.write("%s\n" % bmark, label=label)
815 else:
815 else:
816 ui.write(" %s %-25s %d:%s\n" % (
816 ui.write(" %s %-25s %d:%s\n" % (
817 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
817 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
818 label=label)
818 label=label)
819 return
819 return
820
820
821 @command('branch',
821 @command('branch',
822 [('f', 'force', None,
822 [('f', 'force', None,
823 _('set branch name even if it shadows an existing branch')),
823 _('set branch name even if it shadows an existing branch')),
824 ('C', 'clean', None, _('reset branch name to parent branch name'))],
824 ('C', 'clean', None, _('reset branch name to parent branch name'))],
825 _('[-fC] [NAME]'))
825 _('[-fC] [NAME]'))
826 def branch(ui, repo, label=None, **opts):
826 def branch(ui, repo, label=None, **opts):
827 """set or show the current branch name
827 """set or show the current branch name
828
828
829 .. note::
829 .. note::
830 Branch names are permanent and global. Use :hg:`bookmark` to create a
830 Branch names are permanent and global. Use :hg:`bookmark` to create a
831 light-weight bookmark instead. See :hg:`help glossary` for more
831 light-weight bookmark instead. See :hg:`help glossary` for more
832 information about named branches and bookmarks.
832 information about named branches and bookmarks.
833
833
834 With no argument, show the current branch name. With one argument,
834 With no argument, show the current branch name. With one argument,
835 set the working directory branch name (the branch will not exist
835 set the working directory branch name (the branch will not exist
836 in the repository until the next commit). Standard practice
836 in the repository until the next commit). Standard practice
837 recommends that primary development take place on the 'default'
837 recommends that primary development take place on the 'default'
838 branch.
838 branch.
839
839
840 Unless -f/--force is specified, branch will not let you set a
840 Unless -f/--force is specified, branch will not let you set a
841 branch name that already exists, even if it's inactive.
841 branch name that already exists, even if it's inactive.
842
842
843 Use -C/--clean to reset the working directory branch to that of
843 Use -C/--clean to reset the working directory branch to that of
844 the parent of the working directory, negating a previous branch
844 the parent of the working directory, negating a previous branch
845 change.
845 change.
846
846
847 Use the command :hg:`update` to switch to an existing branch. Use
847 Use the command :hg:`update` to switch to an existing branch. Use
848 :hg:`commit --close-branch` to mark this branch as closed.
848 :hg:`commit --close-branch` to mark this branch as closed.
849
849
850 Returns 0 on success.
850 Returns 0 on success.
851 """
851 """
852
852
853 if opts.get('clean'):
853 if opts.get('clean'):
854 label = repo[None].p1().branch()
854 label = repo[None].p1().branch()
855 repo.dirstate.setbranch(label)
855 repo.dirstate.setbranch(label)
856 ui.status(_('reset working directory to branch %s\n') % label)
856 ui.status(_('reset working directory to branch %s\n') % label)
857 elif label:
857 elif label:
858 if not opts.get('force') and label in repo.branchtags():
858 if not opts.get('force') and label in repo.branchtags():
859 if label not in [p.branch() for p in repo.parents()]:
859 if label not in [p.branch() for p in repo.parents()]:
860 raise util.Abort(_('a branch of the same name already exists'),
860 raise util.Abort(_('a branch of the same name already exists'),
861 # i18n: "it" refers to an existing branch
861 # i18n: "it" refers to an existing branch
862 hint=_("use 'hg update' to switch to it"))
862 hint=_("use 'hg update' to switch to it"))
863 repo.dirstate.setbranch(label)
863 repo.dirstate.setbranch(label)
864 ui.status(_('marked working directory as branch %s\n') % label)
864 ui.status(_('marked working directory as branch %s\n') % label)
865 ui.status(_('(branches are permanent and global, '
866 'did you want a bookmark?)\n'))
865 else:
867 else:
866 ui.write("%s\n" % repo.dirstate.branch())
868 ui.write("%s\n" % repo.dirstate.branch())
867
869
868 @command('branches',
870 @command('branches',
869 [('a', 'active', False, _('show only branches that have unmerged heads')),
871 [('a', 'active', False, _('show only branches that have unmerged heads')),
870 ('c', 'closed', False, _('show normal and closed branches'))],
872 ('c', 'closed', False, _('show normal and closed branches'))],
871 _('[-ac]'))
873 _('[-ac]'))
872 def branches(ui, repo, active=False, closed=False):
874 def branches(ui, repo, active=False, closed=False):
873 """list repository named branches
875 """list repository named branches
874
876
875 List the repository's named branches, indicating which ones are
877 List the repository's named branches, indicating which ones are
876 inactive. If -c/--closed is specified, also list branches which have
878 inactive. If -c/--closed is specified, also list branches which have
877 been marked closed (see :hg:`commit --close-branch`).
879 been marked closed (see :hg:`commit --close-branch`).
878
880
879 If -a/--active is specified, only show active branches. A branch
881 If -a/--active is specified, only show active branches. A branch
880 is considered active if it contains repository heads.
882 is considered active if it contains repository heads.
881
883
882 Use the command :hg:`update` to switch to an existing branch.
884 Use the command :hg:`update` to switch to an existing branch.
883
885
884 Returns 0.
886 Returns 0.
885 """
887 """
886
888
887 hexfunc = ui.debugflag and hex or short
889 hexfunc = ui.debugflag and hex or short
888 activebranches = [repo[n].branch() for n in repo.heads()]
890 activebranches = [repo[n].branch() for n in repo.heads()]
889 def testactive(tag, node):
891 def testactive(tag, node):
890 realhead = tag in activebranches
892 realhead = tag in activebranches
891 open = node in repo.branchheads(tag, closed=False)
893 open = node in repo.branchheads(tag, closed=False)
892 return realhead and open
894 return realhead and open
893 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
895 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
894 for tag, node in repo.branchtags().items()],
896 for tag, node in repo.branchtags().items()],
895 reverse=True)
897 reverse=True)
896
898
897 for isactive, node, tag in branches:
899 for isactive, node, tag in branches:
898 if (not active) or isactive:
900 if (not active) or isactive:
899 if ui.quiet:
901 if ui.quiet:
900 ui.write("%s\n" % tag)
902 ui.write("%s\n" % tag)
901 else:
903 else:
902 hn = repo.lookup(node)
904 hn = repo.lookup(node)
903 if isactive:
905 if isactive:
904 label = 'branches.active'
906 label = 'branches.active'
905 notice = ''
907 notice = ''
906 elif hn not in repo.branchheads(tag, closed=False):
908 elif hn not in repo.branchheads(tag, closed=False):
907 if not closed:
909 if not closed:
908 continue
910 continue
909 label = 'branches.closed'
911 label = 'branches.closed'
910 notice = _(' (closed)')
912 notice = _(' (closed)')
911 else:
913 else:
912 label = 'branches.inactive'
914 label = 'branches.inactive'
913 notice = _(' (inactive)')
915 notice = _(' (inactive)')
914 if tag == repo.dirstate.branch():
916 if tag == repo.dirstate.branch():
915 label = 'branches.current'
917 label = 'branches.current'
916 rev = str(node).rjust(31 - encoding.colwidth(tag))
918 rev = str(node).rjust(31 - encoding.colwidth(tag))
917 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
919 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
918 tag = ui.label(tag, label)
920 tag = ui.label(tag, label)
919 ui.write("%s %s%s\n" % (tag, rev, notice))
921 ui.write("%s %s%s\n" % (tag, rev, notice))
920
922
921 @command('bundle',
923 @command('bundle',
922 [('f', 'force', None, _('run even when the destination is unrelated')),
924 [('f', 'force', None, _('run even when the destination is unrelated')),
923 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
925 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
924 _('REV')),
926 _('REV')),
925 ('b', 'branch', [], _('a specific branch you would like to bundle'),
927 ('b', 'branch', [], _('a specific branch you would like to bundle'),
926 _('BRANCH')),
928 _('BRANCH')),
927 ('', 'base', [],
929 ('', 'base', [],
928 _('a base changeset assumed to be available at the destination'),
930 _('a base changeset assumed to be available at the destination'),
929 _('REV')),
931 _('REV')),
930 ('a', 'all', None, _('bundle all changesets in the repository')),
932 ('a', 'all', None, _('bundle all changesets in the repository')),
931 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
933 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
932 ] + remoteopts,
934 ] + remoteopts,
933 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
935 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
934 def bundle(ui, repo, fname, dest=None, **opts):
936 def bundle(ui, repo, fname, dest=None, **opts):
935 """create a changegroup file
937 """create a changegroup file
936
938
937 Generate a compressed changegroup file collecting changesets not
939 Generate a compressed changegroup file collecting changesets not
938 known to be in another repository.
940 known to be in another repository.
939
941
940 If you omit the destination repository, then hg assumes the
942 If you omit the destination repository, then hg assumes the
941 destination will have all the nodes you specify with --base
943 destination will have all the nodes you specify with --base
942 parameters. To create a bundle containing all changesets, use
944 parameters. To create a bundle containing all changesets, use
943 -a/--all (or --base null).
945 -a/--all (or --base null).
944
946
945 You can change compression method with the -t/--type option.
947 You can change compression method with the -t/--type option.
946 The available compression methods are: none, bzip2, and
948 The available compression methods are: none, bzip2, and
947 gzip (by default, bundles are compressed using bzip2).
949 gzip (by default, bundles are compressed using bzip2).
948
950
949 The bundle file can then be transferred using conventional means
951 The bundle file can then be transferred using conventional means
950 and applied to another repository with the unbundle or pull
952 and applied to another repository with the unbundle or pull
951 command. This is useful when direct push and pull are not
953 command. This is useful when direct push and pull are not
952 available or when exporting an entire repository is undesirable.
954 available or when exporting an entire repository is undesirable.
953
955
954 Applying bundles preserves all changeset contents including
956 Applying bundles preserves all changeset contents including
955 permissions, copy/rename information, and revision history.
957 permissions, copy/rename information, and revision history.
956
958
957 Returns 0 on success, 1 if no changes found.
959 Returns 0 on success, 1 if no changes found.
958 """
960 """
959 revs = None
961 revs = None
960 if 'rev' in opts:
962 if 'rev' in opts:
961 revs = scmutil.revrange(repo, opts['rev'])
963 revs = scmutil.revrange(repo, opts['rev'])
962
964
963 if opts.get('all'):
965 if opts.get('all'):
964 base = ['null']
966 base = ['null']
965 else:
967 else:
966 base = scmutil.revrange(repo, opts.get('base'))
968 base = scmutil.revrange(repo, opts.get('base'))
967 if base:
969 if base:
968 if dest:
970 if dest:
969 raise util.Abort(_("--base is incompatible with specifying "
971 raise util.Abort(_("--base is incompatible with specifying "
970 "a destination"))
972 "a destination"))
971 common = [repo.lookup(rev) for rev in base]
973 common = [repo.lookup(rev) for rev in base]
972 heads = revs and map(repo.lookup, revs) or revs
974 heads = revs and map(repo.lookup, revs) or revs
973 else:
975 else:
974 dest = ui.expandpath(dest or 'default-push', dest or 'default')
976 dest = ui.expandpath(dest or 'default-push', dest or 'default')
975 dest, branches = hg.parseurl(dest, opts.get('branch'))
977 dest, branches = hg.parseurl(dest, opts.get('branch'))
976 other = hg.peer(repo, opts, dest)
978 other = hg.peer(repo, opts, dest)
977 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
979 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
978 heads = revs and map(repo.lookup, revs) or revs
980 heads = revs and map(repo.lookup, revs) or revs
979 common, outheads = discovery.findcommonoutgoing(repo, other,
981 common, outheads = discovery.findcommonoutgoing(repo, other,
980 onlyheads=heads,
982 onlyheads=heads,
981 force=opts.get('force'))
983 force=opts.get('force'))
982
984
983 cg = repo.getbundle('bundle', common=common, heads=heads)
985 cg = repo.getbundle('bundle', common=common, heads=heads)
984 if not cg:
986 if not cg:
985 ui.status(_("no changes found\n"))
987 ui.status(_("no changes found\n"))
986 return 1
988 return 1
987
989
988 bundletype = opts.get('type', 'bzip2').lower()
990 bundletype = opts.get('type', 'bzip2').lower()
989 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
991 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
990 bundletype = btypes.get(bundletype)
992 bundletype = btypes.get(bundletype)
991 if bundletype not in changegroup.bundletypes:
993 if bundletype not in changegroup.bundletypes:
992 raise util.Abort(_('unknown bundle type specified with --type'))
994 raise util.Abort(_('unknown bundle type specified with --type'))
993
995
994 changegroup.writebundle(cg, fname, bundletype)
996 changegroup.writebundle(cg, fname, bundletype)
995
997
996 @command('cat',
998 @command('cat',
997 [('o', 'output', '',
999 [('o', 'output', '',
998 _('print output to file with formatted name'), _('FORMAT')),
1000 _('print output to file with formatted name'), _('FORMAT')),
999 ('r', 'rev', '', _('print the given revision'), _('REV')),
1001 ('r', 'rev', '', _('print the given revision'), _('REV')),
1000 ('', 'decode', None, _('apply any matching decode filter')),
1002 ('', 'decode', None, _('apply any matching decode filter')),
1001 ] + walkopts,
1003 ] + walkopts,
1002 _('[OPTION]... FILE...'))
1004 _('[OPTION]... FILE...'))
1003 def cat(ui, repo, file1, *pats, **opts):
1005 def cat(ui, repo, file1, *pats, **opts):
1004 """output the current or given revision of files
1006 """output the current or given revision of files
1005
1007
1006 Print the specified files as they were at the given revision. If
1008 Print the specified files as they were at the given revision. If
1007 no revision is given, the parent of the working directory is used,
1009 no revision is given, the parent of the working directory is used,
1008 or tip if no revision is checked out.
1010 or tip if no revision is checked out.
1009
1011
1010 Output may be to a file, in which case the name of the file is
1012 Output may be to a file, in which case the name of the file is
1011 given using a format string. The formatting rules are the same as
1013 given using a format string. The formatting rules are the same as
1012 for the export command, with the following additions:
1014 for the export command, with the following additions:
1013
1015
1014 :``%s``: basename of file being printed
1016 :``%s``: basename of file being printed
1015 :``%d``: dirname of file being printed, or '.' if in repository root
1017 :``%d``: dirname of file being printed, or '.' if in repository root
1016 :``%p``: root-relative path name of file being printed
1018 :``%p``: root-relative path name of file being printed
1017
1019
1018 Returns 0 on success.
1020 Returns 0 on success.
1019 """
1021 """
1020 ctx = scmutil.revsingle(repo, opts.get('rev'))
1022 ctx = scmutil.revsingle(repo, opts.get('rev'))
1021 err = 1
1023 err = 1
1022 m = scmutil.match(ctx, (file1,) + pats, opts)
1024 m = scmutil.match(ctx, (file1,) + pats, opts)
1023 for abs in ctx.walk(m):
1025 for abs in ctx.walk(m):
1024 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1026 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1025 pathname=abs)
1027 pathname=abs)
1026 data = ctx[abs].data()
1028 data = ctx[abs].data()
1027 if opts.get('decode'):
1029 if opts.get('decode'):
1028 data = repo.wwritedata(abs, data)
1030 data = repo.wwritedata(abs, data)
1029 fp.write(data)
1031 fp.write(data)
1030 fp.close()
1032 fp.close()
1031 err = 0
1033 err = 0
1032 return err
1034 return err
1033
1035
1034 @command('^clone',
1036 @command('^clone',
1035 [('U', 'noupdate', None,
1037 [('U', 'noupdate', None,
1036 _('the clone will include an empty working copy (only a repository)')),
1038 _('the clone will include an empty working copy (only a repository)')),
1037 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1039 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1038 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1040 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1039 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1041 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1040 ('', 'pull', None, _('use pull protocol to copy metadata')),
1042 ('', 'pull', None, _('use pull protocol to copy metadata')),
1041 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1043 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1042 ] + remoteopts,
1044 ] + remoteopts,
1043 _('[OPTION]... SOURCE [DEST]'))
1045 _('[OPTION]... SOURCE [DEST]'))
1044 def clone(ui, source, dest=None, **opts):
1046 def clone(ui, source, dest=None, **opts):
1045 """make a copy of an existing repository
1047 """make a copy of an existing repository
1046
1048
1047 Create a copy of an existing repository in a new directory.
1049 Create a copy of an existing repository in a new directory.
1048
1050
1049 If no destination directory name is specified, it defaults to the
1051 If no destination directory name is specified, it defaults to the
1050 basename of the source.
1052 basename of the source.
1051
1053
1052 The location of the source is added to the new repository's
1054 The location of the source is added to the new repository's
1053 ``.hg/hgrc`` file, as the default to be used for future pulls.
1055 ``.hg/hgrc`` file, as the default to be used for future pulls.
1054
1056
1055 Only local paths and ``ssh://`` URLs are supported as
1057 Only local paths and ``ssh://`` URLs are supported as
1056 destinations. For ``ssh://`` destinations, no working directory or
1058 destinations. For ``ssh://`` destinations, no working directory or
1057 ``.hg/hgrc`` will be created on the remote side.
1059 ``.hg/hgrc`` will be created on the remote side.
1058
1060
1059 To pull only a subset of changesets, specify one or more revisions
1061 To pull only a subset of changesets, specify one or more revisions
1060 identifiers with -r/--rev or branches with -b/--branch. The
1062 identifiers with -r/--rev or branches with -b/--branch. The
1061 resulting clone will contain only the specified changesets and
1063 resulting clone will contain only the specified changesets and
1062 their ancestors. These options (or 'clone src#rev dest') imply
1064 their ancestors. These options (or 'clone src#rev dest') imply
1063 --pull, even for local source repositories. Note that specifying a
1065 --pull, even for local source repositories. Note that specifying a
1064 tag will include the tagged changeset but not the changeset
1066 tag will include the tagged changeset but not the changeset
1065 containing the tag.
1067 containing the tag.
1066
1068
1067 To check out a particular version, use -u/--update, or
1069 To check out a particular version, use -u/--update, or
1068 -U/--noupdate to create a clone with no working directory.
1070 -U/--noupdate to create a clone with no working directory.
1069
1071
1070 .. container:: verbose
1072 .. container:: verbose
1071
1073
1072 For efficiency, hardlinks are used for cloning whenever the
1074 For efficiency, hardlinks are used for cloning whenever the
1073 source and destination are on the same filesystem (note this
1075 source and destination are on the same filesystem (note this
1074 applies only to the repository data, not to the working
1076 applies only to the repository data, not to the working
1075 directory). Some filesystems, such as AFS, implement hardlinking
1077 directory). Some filesystems, such as AFS, implement hardlinking
1076 incorrectly, but do not report errors. In these cases, use the
1078 incorrectly, but do not report errors. In these cases, use the
1077 --pull option to avoid hardlinking.
1079 --pull option to avoid hardlinking.
1078
1080
1079 In some cases, you can clone repositories and the working
1081 In some cases, you can clone repositories and the working
1080 directory using full hardlinks with ::
1082 directory using full hardlinks with ::
1081
1083
1082 $ cp -al REPO REPOCLONE
1084 $ cp -al REPO REPOCLONE
1083
1085
1084 This is the fastest way to clone, but it is not always safe. The
1086 This is the fastest way to clone, but it is not always safe. The
1085 operation is not atomic (making sure REPO is not modified during
1087 operation is not atomic (making sure REPO is not modified during
1086 the operation is up to you) and you have to make sure your
1088 the operation is up to you) and you have to make sure your
1087 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1089 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1088 so). Also, this is not compatible with certain extensions that
1090 so). Also, this is not compatible with certain extensions that
1089 place their metadata under the .hg directory, such as mq.
1091 place their metadata under the .hg directory, such as mq.
1090
1092
1091 Mercurial will update the working directory to the first applicable
1093 Mercurial will update the working directory to the first applicable
1092 revision from this list:
1094 revision from this list:
1093
1095
1094 a) null if -U or the source repository has no changesets
1096 a) null if -U or the source repository has no changesets
1095 b) if -u . and the source repository is local, the first parent of
1097 b) if -u . and the source repository is local, the first parent of
1096 the source repository's working directory
1098 the source repository's working directory
1097 c) the changeset specified with -u (if a branch name, this means the
1099 c) the changeset specified with -u (if a branch name, this means the
1098 latest head of that branch)
1100 latest head of that branch)
1099 d) the changeset specified with -r
1101 d) the changeset specified with -r
1100 e) the tipmost head specified with -b
1102 e) the tipmost head specified with -b
1101 f) the tipmost head specified with the url#branch source syntax
1103 f) the tipmost head specified with the url#branch source syntax
1102 g) the tipmost head of the default branch
1104 g) the tipmost head of the default branch
1103 h) tip
1105 h) tip
1104
1106
1105 Examples:
1107 Examples:
1106
1108
1107 - clone a remote repository to a new directory named hg/::
1109 - clone a remote repository to a new directory named hg/::
1108
1110
1109 hg clone http://selenic.com/hg
1111 hg clone http://selenic.com/hg
1110
1112
1111 - create a lightweight local clone::
1113 - create a lightweight local clone::
1112
1114
1113 hg clone project/ project-feature/
1115 hg clone project/ project-feature/
1114
1116
1115 - clone from an absolute path on an ssh server (note double-slash)::
1117 - clone from an absolute path on an ssh server (note double-slash)::
1116
1118
1117 hg clone ssh://user@server//home/projects/alpha/
1119 hg clone ssh://user@server//home/projects/alpha/
1118
1120
1119 - do a high-speed clone over a LAN while checking out a
1121 - do a high-speed clone over a LAN while checking out a
1120 specified version::
1122 specified version::
1121
1123
1122 hg clone --uncompressed http://server/repo -u 1.5
1124 hg clone --uncompressed http://server/repo -u 1.5
1123
1125
1124 - create a repository without changesets after a particular revision::
1126 - create a repository without changesets after a particular revision::
1125
1127
1126 hg clone -r 04e544 experimental/ good/
1128 hg clone -r 04e544 experimental/ good/
1127
1129
1128 - clone (and track) a particular named branch::
1130 - clone (and track) a particular named branch::
1129
1131
1130 hg clone http://selenic.com/hg#stable
1132 hg clone http://selenic.com/hg#stable
1131
1133
1132 See :hg:`help urls` for details on specifying URLs.
1134 See :hg:`help urls` for details on specifying URLs.
1133
1135
1134 Returns 0 on success.
1136 Returns 0 on success.
1135 """
1137 """
1136 if opts.get('noupdate') and opts.get('updaterev'):
1138 if opts.get('noupdate') and opts.get('updaterev'):
1137 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1139 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1138
1140
1139 r = hg.clone(ui, opts, source, dest,
1141 r = hg.clone(ui, opts, source, dest,
1140 pull=opts.get('pull'),
1142 pull=opts.get('pull'),
1141 stream=opts.get('uncompressed'),
1143 stream=opts.get('uncompressed'),
1142 rev=opts.get('rev'),
1144 rev=opts.get('rev'),
1143 update=opts.get('updaterev') or not opts.get('noupdate'),
1145 update=opts.get('updaterev') or not opts.get('noupdate'),
1144 branch=opts.get('branch'))
1146 branch=opts.get('branch'))
1145
1147
1146 return r is None
1148 return r is None
1147
1149
1148 @command('^commit|ci',
1150 @command('^commit|ci',
1149 [('A', 'addremove', None,
1151 [('A', 'addremove', None,
1150 _('mark new/missing files as added/removed before committing')),
1152 _('mark new/missing files as added/removed before committing')),
1151 ('', 'close-branch', None,
1153 ('', 'close-branch', None,
1152 _('mark a branch as closed, hiding it from the branch list')),
1154 _('mark a branch as closed, hiding it from the branch list')),
1153 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1155 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1154 _('[OPTION]... [FILE]...'))
1156 _('[OPTION]... [FILE]...'))
1155 def commit(ui, repo, *pats, **opts):
1157 def commit(ui, repo, *pats, **opts):
1156 """commit the specified files or all outstanding changes
1158 """commit the specified files or all outstanding changes
1157
1159
1158 Commit changes to the given files into the repository. Unlike a
1160 Commit changes to the given files into the repository. Unlike a
1159 centralized SCM, this operation is a local operation. See
1161 centralized SCM, this operation is a local operation. See
1160 :hg:`push` for a way to actively distribute your changes.
1162 :hg:`push` for a way to actively distribute your changes.
1161
1163
1162 If a list of files is omitted, all changes reported by :hg:`status`
1164 If a list of files is omitted, all changes reported by :hg:`status`
1163 will be committed.
1165 will be committed.
1164
1166
1165 If you are committing the result of a merge, do not provide any
1167 If you are committing the result of a merge, do not provide any
1166 filenames or -I/-X filters.
1168 filenames or -I/-X filters.
1167
1169
1168 If no commit message is specified, Mercurial starts your
1170 If no commit message is specified, Mercurial starts your
1169 configured editor where you can enter a message. In case your
1171 configured editor where you can enter a message. In case your
1170 commit fails, you will find a backup of your message in
1172 commit fails, you will find a backup of your message in
1171 ``.hg/last-message.txt``.
1173 ``.hg/last-message.txt``.
1172
1174
1173 See :hg:`help dates` for a list of formats valid for -d/--date.
1175 See :hg:`help dates` for a list of formats valid for -d/--date.
1174
1176
1175 Returns 0 on success, 1 if nothing changed.
1177 Returns 0 on success, 1 if nothing changed.
1176 """
1178 """
1177 if opts.get('subrepos'):
1179 if opts.get('subrepos'):
1178 # Let --subrepos on the command line overide config setting.
1180 # Let --subrepos on the command line overide config setting.
1179 ui.setconfig('ui', 'commitsubrepos', True)
1181 ui.setconfig('ui', 'commitsubrepos', True)
1180
1182
1181 extra = {}
1183 extra = {}
1182 if opts.get('close_branch'):
1184 if opts.get('close_branch'):
1183 if repo['.'].node() not in repo.branchheads():
1185 if repo['.'].node() not in repo.branchheads():
1184 # The topo heads set is included in the branch heads set of the
1186 # The topo heads set is included in the branch heads set of the
1185 # current branch, so it's sufficient to test branchheads
1187 # current branch, so it's sufficient to test branchheads
1186 raise util.Abort(_('can only close branch heads'))
1188 raise util.Abort(_('can only close branch heads'))
1187 extra['close'] = 1
1189 extra['close'] = 1
1188 e = cmdutil.commiteditor
1190 e = cmdutil.commiteditor
1189 if opts.get('force_editor'):
1191 if opts.get('force_editor'):
1190 e = cmdutil.commitforceeditor
1192 e = cmdutil.commitforceeditor
1191
1193
1192 def commitfunc(ui, repo, message, match, opts):
1194 def commitfunc(ui, repo, message, match, opts):
1193 return repo.commit(message, opts.get('user'), opts.get('date'), match,
1195 return repo.commit(message, opts.get('user'), opts.get('date'), match,
1194 editor=e, extra=extra)
1196 editor=e, extra=extra)
1195
1197
1196 branch = repo[None].branch()
1198 branch = repo[None].branch()
1197 bheads = repo.branchheads(branch)
1199 bheads = repo.branchheads(branch)
1198
1200
1199 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1201 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1200 if not node:
1202 if not node:
1201 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1203 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1202 if stat[3]:
1204 if stat[3]:
1203 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
1205 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
1204 % len(stat[3]))
1206 % len(stat[3]))
1205 else:
1207 else:
1206 ui.status(_("nothing changed\n"))
1208 ui.status(_("nothing changed\n"))
1207 return 1
1209 return 1
1208
1210
1209 ctx = repo[node]
1211 ctx = repo[node]
1210 parents = ctx.parents()
1212 parents = ctx.parents()
1211
1213
1212 if (bheads and node not in bheads and not
1214 if (bheads and node not in bheads and not
1213 [x for x in parents if x.node() in bheads and x.branch() == branch]):
1215 [x for x in parents if x.node() in bheads and x.branch() == branch]):
1214 ui.status(_('created new head\n'))
1216 ui.status(_('created new head\n'))
1215 # The message is not printed for initial roots. For the other
1217 # The message is not printed for initial roots. For the other
1216 # changesets, it is printed in the following situations:
1218 # changesets, it is printed in the following situations:
1217 #
1219 #
1218 # Par column: for the 2 parents with ...
1220 # Par column: for the 2 parents with ...
1219 # N: null or no parent
1221 # N: null or no parent
1220 # B: parent is on another named branch
1222 # B: parent is on another named branch
1221 # C: parent is a regular non head changeset
1223 # C: parent is a regular non head changeset
1222 # H: parent was a branch head of the current branch
1224 # H: parent was a branch head of the current branch
1223 # Msg column: whether we print "created new head" message
1225 # Msg column: whether we print "created new head" message
1224 # In the following, it is assumed that there already exists some
1226 # In the following, it is assumed that there already exists some
1225 # initial branch heads of the current branch, otherwise nothing is
1227 # initial branch heads of the current branch, otherwise nothing is
1226 # printed anyway.
1228 # printed anyway.
1227 #
1229 #
1228 # Par Msg Comment
1230 # Par Msg Comment
1229 # NN y additional topo root
1231 # NN y additional topo root
1230 #
1232 #
1231 # BN y additional branch root
1233 # BN y additional branch root
1232 # CN y additional topo head
1234 # CN y additional topo head
1233 # HN n usual case
1235 # HN n usual case
1234 #
1236 #
1235 # BB y weird additional branch root
1237 # BB y weird additional branch root
1236 # CB y branch merge
1238 # CB y branch merge
1237 # HB n merge with named branch
1239 # HB n merge with named branch
1238 #
1240 #
1239 # CC y additional head from merge
1241 # CC y additional head from merge
1240 # CH n merge with a head
1242 # CH n merge with a head
1241 #
1243 #
1242 # HH n head merge: head count decreases
1244 # HH n head merge: head count decreases
1243
1245
1244 if not opts.get('close_branch'):
1246 if not opts.get('close_branch'):
1245 for r in parents:
1247 for r in parents:
1246 if r.extra().get('close') and r.branch() == branch:
1248 if r.extra().get('close') and r.branch() == branch:
1247 ui.status(_('reopening closed branch head %d\n') % r)
1249 ui.status(_('reopening closed branch head %d\n') % r)
1248
1250
1249 if ui.debugflag:
1251 if ui.debugflag:
1250 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
1252 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
1251 elif ui.verbose:
1253 elif ui.verbose:
1252 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
1254 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
1253
1255
1254 @command('copy|cp',
1256 @command('copy|cp',
1255 [('A', 'after', None, _('record a copy that has already occurred')),
1257 [('A', 'after', None, _('record a copy that has already occurred')),
1256 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1258 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1257 ] + walkopts + dryrunopts,
1259 ] + walkopts + dryrunopts,
1258 _('[OPTION]... [SOURCE]... DEST'))
1260 _('[OPTION]... [SOURCE]... DEST'))
1259 def copy(ui, repo, *pats, **opts):
1261 def copy(ui, repo, *pats, **opts):
1260 """mark files as copied for the next commit
1262 """mark files as copied for the next commit
1261
1263
1262 Mark dest as having copies of source files. If dest is a
1264 Mark dest as having copies of source files. If dest is a
1263 directory, copies are put in that directory. If dest is a file,
1265 directory, copies are put in that directory. If dest is a file,
1264 the source must be a single file.
1266 the source must be a single file.
1265
1267
1266 By default, this command copies the contents of files as they
1268 By default, this command copies the contents of files as they
1267 exist in the working directory. If invoked with -A/--after, the
1269 exist in the working directory. If invoked with -A/--after, the
1268 operation is recorded, but no copying is performed.
1270 operation is recorded, but no copying is performed.
1269
1271
1270 This command takes effect with the next commit. To undo a copy
1272 This command takes effect with the next commit. To undo a copy
1271 before that, see :hg:`revert`.
1273 before that, see :hg:`revert`.
1272
1274
1273 Returns 0 on success, 1 if errors are encountered.
1275 Returns 0 on success, 1 if errors are encountered.
1274 """
1276 """
1275 wlock = repo.wlock(False)
1277 wlock = repo.wlock(False)
1276 try:
1278 try:
1277 return cmdutil.copy(ui, repo, pats, opts)
1279 return cmdutil.copy(ui, repo, pats, opts)
1278 finally:
1280 finally:
1279 wlock.release()
1281 wlock.release()
1280
1282
1281 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1283 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1282 def debugancestor(ui, repo, *args):
1284 def debugancestor(ui, repo, *args):
1283 """find the ancestor revision of two revisions in a given index"""
1285 """find the ancestor revision of two revisions in a given index"""
1284 if len(args) == 3:
1286 if len(args) == 3:
1285 index, rev1, rev2 = args
1287 index, rev1, rev2 = args
1286 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1288 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1287 lookup = r.lookup
1289 lookup = r.lookup
1288 elif len(args) == 2:
1290 elif len(args) == 2:
1289 if not repo:
1291 if not repo:
1290 raise util.Abort(_("there is no Mercurial repository here "
1292 raise util.Abort(_("there is no Mercurial repository here "
1291 "(.hg not found)"))
1293 "(.hg not found)"))
1292 rev1, rev2 = args
1294 rev1, rev2 = args
1293 r = repo.changelog
1295 r = repo.changelog
1294 lookup = repo.lookup
1296 lookup = repo.lookup
1295 else:
1297 else:
1296 raise util.Abort(_('either two or three arguments required'))
1298 raise util.Abort(_('either two or three arguments required'))
1297 a = r.ancestor(lookup(rev1), lookup(rev2))
1299 a = r.ancestor(lookup(rev1), lookup(rev2))
1298 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1300 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1299
1301
1300 @command('debugbuilddag',
1302 @command('debugbuilddag',
1301 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1303 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1302 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1304 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1303 ('n', 'new-file', None, _('add new file at each rev'))],
1305 ('n', 'new-file', None, _('add new file at each rev'))],
1304 _('[OPTION]... [TEXT]'))
1306 _('[OPTION]... [TEXT]'))
1305 def debugbuilddag(ui, repo, text=None,
1307 def debugbuilddag(ui, repo, text=None,
1306 mergeable_file=False,
1308 mergeable_file=False,
1307 overwritten_file=False,
1309 overwritten_file=False,
1308 new_file=False):
1310 new_file=False):
1309 """builds a repo with a given DAG from scratch in the current empty repo
1311 """builds a repo with a given DAG from scratch in the current empty repo
1310
1312
1311 The description of the DAG is read from stdin if not given on the
1313 The description of the DAG is read from stdin if not given on the
1312 command line.
1314 command line.
1313
1315
1314 Elements:
1316 Elements:
1315
1317
1316 - "+n" is a linear run of n nodes based on the current default parent
1318 - "+n" is a linear run of n nodes based on the current default parent
1317 - "." is a single node based on the current default parent
1319 - "." is a single node based on the current default parent
1318 - "$" resets the default parent to null (implied at the start);
1320 - "$" resets the default parent to null (implied at the start);
1319 otherwise the default parent is always the last node created
1321 otherwise the default parent is always the last node created
1320 - "<p" sets the default parent to the backref p
1322 - "<p" sets the default parent to the backref p
1321 - "*p" is a fork at parent p, which is a backref
1323 - "*p" is a fork at parent p, which is a backref
1322 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1324 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1323 - "/p2" is a merge of the preceding node and p2
1325 - "/p2" is a merge of the preceding node and p2
1324 - ":tag" defines a local tag for the preceding node
1326 - ":tag" defines a local tag for the preceding node
1325 - "@branch" sets the named branch for subsequent nodes
1327 - "@branch" sets the named branch for subsequent nodes
1326 - "#...\\n" is a comment up to the end of the line
1328 - "#...\\n" is a comment up to the end of the line
1327
1329
1328 Whitespace between the above elements is ignored.
1330 Whitespace between the above elements is ignored.
1329
1331
1330 A backref is either
1332 A backref is either
1331
1333
1332 - a number n, which references the node curr-n, where curr is the current
1334 - a number n, which references the node curr-n, where curr is the current
1333 node, or
1335 node, or
1334 - the name of a local tag you placed earlier using ":tag", or
1336 - the name of a local tag you placed earlier using ":tag", or
1335 - empty to denote the default parent.
1337 - empty to denote the default parent.
1336
1338
1337 All string valued-elements are either strictly alphanumeric, or must
1339 All string valued-elements are either strictly alphanumeric, or must
1338 be enclosed in double quotes ("..."), with "\\" as escape character.
1340 be enclosed in double quotes ("..."), with "\\" as escape character.
1339 """
1341 """
1340
1342
1341 if text is None:
1343 if text is None:
1342 ui.status(_("reading DAG from stdin\n"))
1344 ui.status(_("reading DAG from stdin\n"))
1343 text = ui.fin.read()
1345 text = ui.fin.read()
1344
1346
1345 cl = repo.changelog
1347 cl = repo.changelog
1346 if len(cl) > 0:
1348 if len(cl) > 0:
1347 raise util.Abort(_('repository is not empty'))
1349 raise util.Abort(_('repository is not empty'))
1348
1350
1349 # determine number of revs in DAG
1351 # determine number of revs in DAG
1350 total = 0
1352 total = 0
1351 for type, data in dagparser.parsedag(text):
1353 for type, data in dagparser.parsedag(text):
1352 if type == 'n':
1354 if type == 'n':
1353 total += 1
1355 total += 1
1354
1356
1355 if mergeable_file:
1357 if mergeable_file:
1356 linesperrev = 2
1358 linesperrev = 2
1357 # make a file with k lines per rev
1359 # make a file with k lines per rev
1358 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1360 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1359 initialmergedlines.append("")
1361 initialmergedlines.append("")
1360
1362
1361 tags = []
1363 tags = []
1362
1364
1363 tr = repo.transaction("builddag")
1365 tr = repo.transaction("builddag")
1364 try:
1366 try:
1365
1367
1366 at = -1
1368 at = -1
1367 atbranch = 'default'
1369 atbranch = 'default'
1368 nodeids = []
1370 nodeids = []
1369 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1371 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1370 for type, data in dagparser.parsedag(text):
1372 for type, data in dagparser.parsedag(text):
1371 if type == 'n':
1373 if type == 'n':
1372 ui.note('node %s\n' % str(data))
1374 ui.note('node %s\n' % str(data))
1373 id, ps = data
1375 id, ps = data
1374
1376
1375 files = []
1377 files = []
1376 fctxs = {}
1378 fctxs = {}
1377
1379
1378 p2 = None
1380 p2 = None
1379 if mergeable_file:
1381 if mergeable_file:
1380 fn = "mf"
1382 fn = "mf"
1381 p1 = repo[ps[0]]
1383 p1 = repo[ps[0]]
1382 if len(ps) > 1:
1384 if len(ps) > 1:
1383 p2 = repo[ps[1]]
1385 p2 = repo[ps[1]]
1384 pa = p1.ancestor(p2)
1386 pa = p1.ancestor(p2)
1385 base, local, other = [x[fn].data() for x in pa, p1, p2]
1387 base, local, other = [x[fn].data() for x in pa, p1, p2]
1386 m3 = simplemerge.Merge3Text(base, local, other)
1388 m3 = simplemerge.Merge3Text(base, local, other)
1387 ml = [l.strip() for l in m3.merge_lines()]
1389 ml = [l.strip() for l in m3.merge_lines()]
1388 ml.append("")
1390 ml.append("")
1389 elif at > 0:
1391 elif at > 0:
1390 ml = p1[fn].data().split("\n")
1392 ml = p1[fn].data().split("\n")
1391 else:
1393 else:
1392 ml = initialmergedlines
1394 ml = initialmergedlines
1393 ml[id * linesperrev] += " r%i" % id
1395 ml[id * linesperrev] += " r%i" % id
1394 mergedtext = "\n".join(ml)
1396 mergedtext = "\n".join(ml)
1395 files.append(fn)
1397 files.append(fn)
1396 fctxs[fn] = context.memfilectx(fn, mergedtext)
1398 fctxs[fn] = context.memfilectx(fn, mergedtext)
1397
1399
1398 if overwritten_file:
1400 if overwritten_file:
1399 fn = "of"
1401 fn = "of"
1400 files.append(fn)
1402 files.append(fn)
1401 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1403 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1402
1404
1403 if new_file:
1405 if new_file:
1404 fn = "nf%i" % id
1406 fn = "nf%i" % id
1405 files.append(fn)
1407 files.append(fn)
1406 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1408 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1407 if len(ps) > 1:
1409 if len(ps) > 1:
1408 if not p2:
1410 if not p2:
1409 p2 = repo[ps[1]]
1411 p2 = repo[ps[1]]
1410 for fn in p2:
1412 for fn in p2:
1411 if fn.startswith("nf"):
1413 if fn.startswith("nf"):
1412 files.append(fn)
1414 files.append(fn)
1413 fctxs[fn] = p2[fn]
1415 fctxs[fn] = p2[fn]
1414
1416
1415 def fctxfn(repo, cx, path):
1417 def fctxfn(repo, cx, path):
1416 return fctxs.get(path)
1418 return fctxs.get(path)
1417
1419
1418 if len(ps) == 0 or ps[0] < 0:
1420 if len(ps) == 0 or ps[0] < 0:
1419 pars = [None, None]
1421 pars = [None, None]
1420 elif len(ps) == 1:
1422 elif len(ps) == 1:
1421 pars = [nodeids[ps[0]], None]
1423 pars = [nodeids[ps[0]], None]
1422 else:
1424 else:
1423 pars = [nodeids[p] for p in ps]
1425 pars = [nodeids[p] for p in ps]
1424 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1426 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1425 date=(id, 0),
1427 date=(id, 0),
1426 user="debugbuilddag",
1428 user="debugbuilddag",
1427 extra={'branch': atbranch})
1429 extra={'branch': atbranch})
1428 nodeid = repo.commitctx(cx)
1430 nodeid = repo.commitctx(cx)
1429 nodeids.append(nodeid)
1431 nodeids.append(nodeid)
1430 at = id
1432 at = id
1431 elif type == 'l':
1433 elif type == 'l':
1432 id, name = data
1434 id, name = data
1433 ui.note('tag %s\n' % name)
1435 ui.note('tag %s\n' % name)
1434 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1436 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1435 elif type == 'a':
1437 elif type == 'a':
1436 ui.note('branch %s\n' % data)
1438 ui.note('branch %s\n' % data)
1437 atbranch = data
1439 atbranch = data
1438 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1440 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1439 tr.close()
1441 tr.close()
1440 finally:
1442 finally:
1441 ui.progress(_('building'), None)
1443 ui.progress(_('building'), None)
1442 tr.release()
1444 tr.release()
1443
1445
1444 if tags:
1446 if tags:
1445 repo.opener.write("localtags", "".join(tags))
1447 repo.opener.write("localtags", "".join(tags))
1446
1448
1447 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1449 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1448 def debugbundle(ui, bundlepath, all=None, **opts):
1450 def debugbundle(ui, bundlepath, all=None, **opts):
1449 """lists the contents of a bundle"""
1451 """lists the contents of a bundle"""
1450 f = url.open(ui, bundlepath)
1452 f = url.open(ui, bundlepath)
1451 try:
1453 try:
1452 gen = changegroup.readbundle(f, bundlepath)
1454 gen = changegroup.readbundle(f, bundlepath)
1453 if all:
1455 if all:
1454 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1456 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1455
1457
1456 def showchunks(named):
1458 def showchunks(named):
1457 ui.write("\n%s\n" % named)
1459 ui.write("\n%s\n" % named)
1458 chain = None
1460 chain = None
1459 while True:
1461 while True:
1460 chunkdata = gen.deltachunk(chain)
1462 chunkdata = gen.deltachunk(chain)
1461 if not chunkdata:
1463 if not chunkdata:
1462 break
1464 break
1463 node = chunkdata['node']
1465 node = chunkdata['node']
1464 p1 = chunkdata['p1']
1466 p1 = chunkdata['p1']
1465 p2 = chunkdata['p2']
1467 p2 = chunkdata['p2']
1466 cs = chunkdata['cs']
1468 cs = chunkdata['cs']
1467 deltabase = chunkdata['deltabase']
1469 deltabase = chunkdata['deltabase']
1468 delta = chunkdata['delta']
1470 delta = chunkdata['delta']
1469 ui.write("%s %s %s %s %s %s\n" %
1471 ui.write("%s %s %s %s %s %s\n" %
1470 (hex(node), hex(p1), hex(p2),
1472 (hex(node), hex(p1), hex(p2),
1471 hex(cs), hex(deltabase), len(delta)))
1473 hex(cs), hex(deltabase), len(delta)))
1472 chain = node
1474 chain = node
1473
1475
1474 chunkdata = gen.changelogheader()
1476 chunkdata = gen.changelogheader()
1475 showchunks("changelog")
1477 showchunks("changelog")
1476 chunkdata = gen.manifestheader()
1478 chunkdata = gen.manifestheader()
1477 showchunks("manifest")
1479 showchunks("manifest")
1478 while True:
1480 while True:
1479 chunkdata = gen.filelogheader()
1481 chunkdata = gen.filelogheader()
1480 if not chunkdata:
1482 if not chunkdata:
1481 break
1483 break
1482 fname = chunkdata['filename']
1484 fname = chunkdata['filename']
1483 showchunks(fname)
1485 showchunks(fname)
1484 else:
1486 else:
1485 chunkdata = gen.changelogheader()
1487 chunkdata = gen.changelogheader()
1486 chain = None
1488 chain = None
1487 while True:
1489 while True:
1488 chunkdata = gen.deltachunk(chain)
1490 chunkdata = gen.deltachunk(chain)
1489 if not chunkdata:
1491 if not chunkdata:
1490 break
1492 break
1491 node = chunkdata['node']
1493 node = chunkdata['node']
1492 ui.write("%s\n" % hex(node))
1494 ui.write("%s\n" % hex(node))
1493 chain = node
1495 chain = node
1494 finally:
1496 finally:
1495 f.close()
1497 f.close()
1496
1498
1497 @command('debugcheckstate', [], '')
1499 @command('debugcheckstate', [], '')
1498 def debugcheckstate(ui, repo):
1500 def debugcheckstate(ui, repo):
1499 """validate the correctness of the current dirstate"""
1501 """validate the correctness of the current dirstate"""
1500 parent1, parent2 = repo.dirstate.parents()
1502 parent1, parent2 = repo.dirstate.parents()
1501 m1 = repo[parent1].manifest()
1503 m1 = repo[parent1].manifest()
1502 m2 = repo[parent2].manifest()
1504 m2 = repo[parent2].manifest()
1503 errors = 0
1505 errors = 0
1504 for f in repo.dirstate:
1506 for f in repo.dirstate:
1505 state = repo.dirstate[f]
1507 state = repo.dirstate[f]
1506 if state in "nr" and f not in m1:
1508 if state in "nr" and f not in m1:
1507 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1509 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1508 errors += 1
1510 errors += 1
1509 if state in "a" and f in m1:
1511 if state in "a" and f in m1:
1510 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1512 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1511 errors += 1
1513 errors += 1
1512 if state in "m" and f not in m1 and f not in m2:
1514 if state in "m" and f not in m1 and f not in m2:
1513 ui.warn(_("%s in state %s, but not in either manifest\n") %
1515 ui.warn(_("%s in state %s, but not in either manifest\n") %
1514 (f, state))
1516 (f, state))
1515 errors += 1
1517 errors += 1
1516 for f in m1:
1518 for f in m1:
1517 state = repo.dirstate[f]
1519 state = repo.dirstate[f]
1518 if state not in "nrm":
1520 if state not in "nrm":
1519 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1521 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1520 errors += 1
1522 errors += 1
1521 if errors:
1523 if errors:
1522 error = _(".hg/dirstate inconsistent with current parent's manifest")
1524 error = _(".hg/dirstate inconsistent with current parent's manifest")
1523 raise util.Abort(error)
1525 raise util.Abort(error)
1524
1526
1525 @command('debugcommands', [], _('[COMMAND]'))
1527 @command('debugcommands', [], _('[COMMAND]'))
1526 def debugcommands(ui, cmd='', *args):
1528 def debugcommands(ui, cmd='', *args):
1527 """list all available commands and options"""
1529 """list all available commands and options"""
1528 for cmd, vals in sorted(table.iteritems()):
1530 for cmd, vals in sorted(table.iteritems()):
1529 cmd = cmd.split('|')[0].strip('^')
1531 cmd = cmd.split('|')[0].strip('^')
1530 opts = ', '.join([i[1] for i in vals[1]])
1532 opts = ', '.join([i[1] for i in vals[1]])
1531 ui.write('%s: %s\n' % (cmd, opts))
1533 ui.write('%s: %s\n' % (cmd, opts))
1532
1534
1533 @command('debugcomplete',
1535 @command('debugcomplete',
1534 [('o', 'options', None, _('show the command options'))],
1536 [('o', 'options', None, _('show the command options'))],
1535 _('[-o] CMD'))
1537 _('[-o] CMD'))
1536 def debugcomplete(ui, cmd='', **opts):
1538 def debugcomplete(ui, cmd='', **opts):
1537 """returns the completion list associated with the given command"""
1539 """returns the completion list associated with the given command"""
1538
1540
1539 if opts.get('options'):
1541 if opts.get('options'):
1540 options = []
1542 options = []
1541 otables = [globalopts]
1543 otables = [globalopts]
1542 if cmd:
1544 if cmd:
1543 aliases, entry = cmdutil.findcmd(cmd, table, False)
1545 aliases, entry = cmdutil.findcmd(cmd, table, False)
1544 otables.append(entry[1])
1546 otables.append(entry[1])
1545 for t in otables:
1547 for t in otables:
1546 for o in t:
1548 for o in t:
1547 if "(DEPRECATED)" in o[3]:
1549 if "(DEPRECATED)" in o[3]:
1548 continue
1550 continue
1549 if o[0]:
1551 if o[0]:
1550 options.append('-%s' % o[0])
1552 options.append('-%s' % o[0])
1551 options.append('--%s' % o[1])
1553 options.append('--%s' % o[1])
1552 ui.write("%s\n" % "\n".join(options))
1554 ui.write("%s\n" % "\n".join(options))
1553 return
1555 return
1554
1556
1555 cmdlist = cmdutil.findpossible(cmd, table)
1557 cmdlist = cmdutil.findpossible(cmd, table)
1556 if ui.verbose:
1558 if ui.verbose:
1557 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1559 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1558 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1560 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1559
1561
1560 @command('debugdag',
1562 @command('debugdag',
1561 [('t', 'tags', None, _('use tags as labels')),
1563 [('t', 'tags', None, _('use tags as labels')),
1562 ('b', 'branches', None, _('annotate with branch names')),
1564 ('b', 'branches', None, _('annotate with branch names')),
1563 ('', 'dots', None, _('use dots for runs')),
1565 ('', 'dots', None, _('use dots for runs')),
1564 ('s', 'spaces', None, _('separate elements by spaces'))],
1566 ('s', 'spaces', None, _('separate elements by spaces'))],
1565 _('[OPTION]... [FILE [REV]...]'))
1567 _('[OPTION]... [FILE [REV]...]'))
1566 def debugdag(ui, repo, file_=None, *revs, **opts):
1568 def debugdag(ui, repo, file_=None, *revs, **opts):
1567 """format the changelog or an index DAG as a concise textual description
1569 """format the changelog or an index DAG as a concise textual description
1568
1570
1569 If you pass a revlog index, the revlog's DAG is emitted. If you list
1571 If you pass a revlog index, the revlog's DAG is emitted. If you list
1570 revision numbers, they get labelled in the output as rN.
1572 revision numbers, they get labelled in the output as rN.
1571
1573
1572 Otherwise, the changelog DAG of the current repo is emitted.
1574 Otherwise, the changelog DAG of the current repo is emitted.
1573 """
1575 """
1574 spaces = opts.get('spaces')
1576 spaces = opts.get('spaces')
1575 dots = opts.get('dots')
1577 dots = opts.get('dots')
1576 if file_:
1578 if file_:
1577 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1579 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1578 revs = set((int(r) for r in revs))
1580 revs = set((int(r) for r in revs))
1579 def events():
1581 def events():
1580 for r in rlog:
1582 for r in rlog:
1581 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1583 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1582 if r in revs:
1584 if r in revs:
1583 yield 'l', (r, "r%i" % r)
1585 yield 'l', (r, "r%i" % r)
1584 elif repo:
1586 elif repo:
1585 cl = repo.changelog
1587 cl = repo.changelog
1586 tags = opts.get('tags')
1588 tags = opts.get('tags')
1587 branches = opts.get('branches')
1589 branches = opts.get('branches')
1588 if tags:
1590 if tags:
1589 labels = {}
1591 labels = {}
1590 for l, n in repo.tags().items():
1592 for l, n in repo.tags().items():
1591 labels.setdefault(cl.rev(n), []).append(l)
1593 labels.setdefault(cl.rev(n), []).append(l)
1592 def events():
1594 def events():
1593 b = "default"
1595 b = "default"
1594 for r in cl:
1596 for r in cl:
1595 if branches:
1597 if branches:
1596 newb = cl.read(cl.node(r))[5]['branch']
1598 newb = cl.read(cl.node(r))[5]['branch']
1597 if newb != b:
1599 if newb != b:
1598 yield 'a', newb
1600 yield 'a', newb
1599 b = newb
1601 b = newb
1600 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1602 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1601 if tags:
1603 if tags:
1602 ls = labels.get(r)
1604 ls = labels.get(r)
1603 if ls:
1605 if ls:
1604 for l in ls:
1606 for l in ls:
1605 yield 'l', (r, l)
1607 yield 'l', (r, l)
1606 else:
1608 else:
1607 raise util.Abort(_('need repo for changelog dag'))
1609 raise util.Abort(_('need repo for changelog dag'))
1608
1610
1609 for line in dagparser.dagtextlines(events(),
1611 for line in dagparser.dagtextlines(events(),
1610 addspaces=spaces,
1612 addspaces=spaces,
1611 wraplabels=True,
1613 wraplabels=True,
1612 wrapannotations=True,
1614 wrapannotations=True,
1613 wrapnonlinear=dots,
1615 wrapnonlinear=dots,
1614 usedots=dots,
1616 usedots=dots,
1615 maxlinewidth=70):
1617 maxlinewidth=70):
1616 ui.write(line)
1618 ui.write(line)
1617 ui.write("\n")
1619 ui.write("\n")
1618
1620
1619 @command('debugdata',
1621 @command('debugdata',
1620 [('c', 'changelog', False, _('open changelog')),
1622 [('c', 'changelog', False, _('open changelog')),
1621 ('m', 'manifest', False, _('open manifest'))],
1623 ('m', 'manifest', False, _('open manifest'))],
1622 _('-c|-m|FILE REV'))
1624 _('-c|-m|FILE REV'))
1623 def debugdata(ui, repo, file_, rev = None, **opts):
1625 def debugdata(ui, repo, file_, rev = None, **opts):
1624 """dump the contents of a data file revision"""
1626 """dump the contents of a data file revision"""
1625 if opts.get('changelog') or opts.get('manifest'):
1627 if opts.get('changelog') or opts.get('manifest'):
1626 file_, rev = None, file_
1628 file_, rev = None, file_
1627 elif rev is None:
1629 elif rev is None:
1628 raise error.CommandError('debugdata', _('invalid arguments'))
1630 raise error.CommandError('debugdata', _('invalid arguments'))
1629 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1631 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1630 try:
1632 try:
1631 ui.write(r.revision(r.lookup(rev)))
1633 ui.write(r.revision(r.lookup(rev)))
1632 except KeyError:
1634 except KeyError:
1633 raise util.Abort(_('invalid revision identifier %s') % rev)
1635 raise util.Abort(_('invalid revision identifier %s') % rev)
1634
1636
1635 @command('debugdate',
1637 @command('debugdate',
1636 [('e', 'extended', None, _('try extended date formats'))],
1638 [('e', 'extended', None, _('try extended date formats'))],
1637 _('[-e] DATE [RANGE]'))
1639 _('[-e] DATE [RANGE]'))
1638 def debugdate(ui, date, range=None, **opts):
1640 def debugdate(ui, date, range=None, **opts):
1639 """parse and display a date"""
1641 """parse and display a date"""
1640 if opts["extended"]:
1642 if opts["extended"]:
1641 d = util.parsedate(date, util.extendeddateformats)
1643 d = util.parsedate(date, util.extendeddateformats)
1642 else:
1644 else:
1643 d = util.parsedate(date)
1645 d = util.parsedate(date)
1644 ui.write("internal: %s %s\n" % d)
1646 ui.write("internal: %s %s\n" % d)
1645 ui.write("standard: %s\n" % util.datestr(d))
1647 ui.write("standard: %s\n" % util.datestr(d))
1646 if range:
1648 if range:
1647 m = util.matchdate(range)
1649 m = util.matchdate(range)
1648 ui.write("match: %s\n" % m(d[0]))
1650 ui.write("match: %s\n" % m(d[0]))
1649
1651
1650 @command('debugdiscovery',
1652 @command('debugdiscovery',
1651 [('', 'old', None, _('use old-style discovery')),
1653 [('', 'old', None, _('use old-style discovery')),
1652 ('', 'nonheads', None,
1654 ('', 'nonheads', None,
1653 _('use old-style discovery with non-heads included')),
1655 _('use old-style discovery with non-heads included')),
1654 ] + remoteopts,
1656 ] + remoteopts,
1655 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1657 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1656 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1658 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1657 """runs the changeset discovery protocol in isolation"""
1659 """runs the changeset discovery protocol in isolation"""
1658 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1660 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1659 remote = hg.peer(repo, opts, remoteurl)
1661 remote = hg.peer(repo, opts, remoteurl)
1660 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1662 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1661
1663
1662 # make sure tests are repeatable
1664 # make sure tests are repeatable
1663 random.seed(12323)
1665 random.seed(12323)
1664
1666
1665 def doit(localheads, remoteheads):
1667 def doit(localheads, remoteheads):
1666 if opts.get('old'):
1668 if opts.get('old'):
1667 if localheads:
1669 if localheads:
1668 raise util.Abort('cannot use localheads with old style discovery')
1670 raise util.Abort('cannot use localheads with old style discovery')
1669 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1671 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1670 force=True)
1672 force=True)
1671 common = set(common)
1673 common = set(common)
1672 if not opts.get('nonheads'):
1674 if not opts.get('nonheads'):
1673 ui.write("unpruned common: %s\n" % " ".join([short(n)
1675 ui.write("unpruned common: %s\n" % " ".join([short(n)
1674 for n in common]))
1676 for n in common]))
1675 dag = dagutil.revlogdag(repo.changelog)
1677 dag = dagutil.revlogdag(repo.changelog)
1676 all = dag.ancestorset(dag.internalizeall(common))
1678 all = dag.ancestorset(dag.internalizeall(common))
1677 common = dag.externalizeall(dag.headsetofconnecteds(all))
1679 common = dag.externalizeall(dag.headsetofconnecteds(all))
1678 else:
1680 else:
1679 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1681 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1680 common = set(common)
1682 common = set(common)
1681 rheads = set(hds)
1683 rheads = set(hds)
1682 lheads = set(repo.heads())
1684 lheads = set(repo.heads())
1683 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1685 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1684 if lheads <= common:
1686 if lheads <= common:
1685 ui.write("local is subset\n")
1687 ui.write("local is subset\n")
1686 elif rheads <= common:
1688 elif rheads <= common:
1687 ui.write("remote is subset\n")
1689 ui.write("remote is subset\n")
1688
1690
1689 serverlogs = opts.get('serverlog')
1691 serverlogs = opts.get('serverlog')
1690 if serverlogs:
1692 if serverlogs:
1691 for filename in serverlogs:
1693 for filename in serverlogs:
1692 logfile = open(filename, 'r')
1694 logfile = open(filename, 'r')
1693 try:
1695 try:
1694 line = logfile.readline()
1696 line = logfile.readline()
1695 while line:
1697 while line:
1696 parts = line.strip().split(';')
1698 parts = line.strip().split(';')
1697 op = parts[1]
1699 op = parts[1]
1698 if op == 'cg':
1700 if op == 'cg':
1699 pass
1701 pass
1700 elif op == 'cgss':
1702 elif op == 'cgss':
1701 doit(parts[2].split(' '), parts[3].split(' '))
1703 doit(parts[2].split(' '), parts[3].split(' '))
1702 elif op == 'unb':
1704 elif op == 'unb':
1703 doit(parts[3].split(' '), parts[2].split(' '))
1705 doit(parts[3].split(' '), parts[2].split(' '))
1704 line = logfile.readline()
1706 line = logfile.readline()
1705 finally:
1707 finally:
1706 logfile.close()
1708 logfile.close()
1707
1709
1708 else:
1710 else:
1709 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1711 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1710 opts.get('remote_head'))
1712 opts.get('remote_head'))
1711 localrevs = opts.get('local_head')
1713 localrevs = opts.get('local_head')
1712 doit(localrevs, remoterevs)
1714 doit(localrevs, remoterevs)
1713
1715
1714 @command('debugfileset', [], ('REVSPEC'))
1716 @command('debugfileset', [], ('REVSPEC'))
1715 def debugfileset(ui, repo, expr):
1717 def debugfileset(ui, repo, expr):
1716 '''parse and apply a fileset specification'''
1718 '''parse and apply a fileset specification'''
1717 if ui.verbose:
1719 if ui.verbose:
1718 tree = fileset.parse(expr)[0]
1720 tree = fileset.parse(expr)[0]
1719 ui.note(tree, "\n")
1721 ui.note(tree, "\n")
1720
1722
1721 for f in fileset.getfileset(repo[None], expr):
1723 for f in fileset.getfileset(repo[None], expr):
1722 ui.write("%s\n" % f)
1724 ui.write("%s\n" % f)
1723
1725
1724 @command('debugfsinfo', [], _('[PATH]'))
1726 @command('debugfsinfo', [], _('[PATH]'))
1725 def debugfsinfo(ui, path = "."):
1727 def debugfsinfo(ui, path = "."):
1726 """show information detected about current filesystem"""
1728 """show information detected about current filesystem"""
1727 util.writefile('.debugfsinfo', '')
1729 util.writefile('.debugfsinfo', '')
1728 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1730 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1729 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1731 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1730 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1732 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1731 and 'yes' or 'no'))
1733 and 'yes' or 'no'))
1732 os.unlink('.debugfsinfo')
1734 os.unlink('.debugfsinfo')
1733
1735
1734 @command('debuggetbundle',
1736 @command('debuggetbundle',
1735 [('H', 'head', [], _('id of head node'), _('ID')),
1737 [('H', 'head', [], _('id of head node'), _('ID')),
1736 ('C', 'common', [], _('id of common node'), _('ID')),
1738 ('C', 'common', [], _('id of common node'), _('ID')),
1737 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1739 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1738 _('REPO FILE [-H|-C ID]...'))
1740 _('REPO FILE [-H|-C ID]...'))
1739 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1741 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1740 """retrieves a bundle from a repo
1742 """retrieves a bundle from a repo
1741
1743
1742 Every ID must be a full-length hex node id string. Saves the bundle to the
1744 Every ID must be a full-length hex node id string. Saves the bundle to the
1743 given file.
1745 given file.
1744 """
1746 """
1745 repo = hg.peer(ui, opts, repopath)
1747 repo = hg.peer(ui, opts, repopath)
1746 if not repo.capable('getbundle'):
1748 if not repo.capable('getbundle'):
1747 raise util.Abort("getbundle() not supported by target repository")
1749 raise util.Abort("getbundle() not supported by target repository")
1748 args = {}
1750 args = {}
1749 if common:
1751 if common:
1750 args['common'] = [bin(s) for s in common]
1752 args['common'] = [bin(s) for s in common]
1751 if head:
1753 if head:
1752 args['heads'] = [bin(s) for s in head]
1754 args['heads'] = [bin(s) for s in head]
1753 bundle = repo.getbundle('debug', **args)
1755 bundle = repo.getbundle('debug', **args)
1754
1756
1755 bundletype = opts.get('type', 'bzip2').lower()
1757 bundletype = opts.get('type', 'bzip2').lower()
1756 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1758 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1757 bundletype = btypes.get(bundletype)
1759 bundletype = btypes.get(bundletype)
1758 if bundletype not in changegroup.bundletypes:
1760 if bundletype not in changegroup.bundletypes:
1759 raise util.Abort(_('unknown bundle type specified with --type'))
1761 raise util.Abort(_('unknown bundle type specified with --type'))
1760 changegroup.writebundle(bundle, bundlepath, bundletype)
1762 changegroup.writebundle(bundle, bundlepath, bundletype)
1761
1763
1762 @command('debugignore', [], '')
1764 @command('debugignore', [], '')
1763 def debugignore(ui, repo, *values, **opts):
1765 def debugignore(ui, repo, *values, **opts):
1764 """display the combined ignore pattern"""
1766 """display the combined ignore pattern"""
1765 ignore = repo.dirstate._ignore
1767 ignore = repo.dirstate._ignore
1766 includepat = getattr(ignore, 'includepat', None)
1768 includepat = getattr(ignore, 'includepat', None)
1767 if includepat is not None:
1769 if includepat is not None:
1768 ui.write("%s\n" % includepat)
1770 ui.write("%s\n" % includepat)
1769 else:
1771 else:
1770 raise util.Abort(_("no ignore patterns found"))
1772 raise util.Abort(_("no ignore patterns found"))
1771
1773
1772 @command('debugindex',
1774 @command('debugindex',
1773 [('c', 'changelog', False, _('open changelog')),
1775 [('c', 'changelog', False, _('open changelog')),
1774 ('m', 'manifest', False, _('open manifest')),
1776 ('m', 'manifest', False, _('open manifest')),
1775 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1777 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1776 _('[-f FORMAT] -c|-m|FILE'))
1778 _('[-f FORMAT] -c|-m|FILE'))
1777 def debugindex(ui, repo, file_ = None, **opts):
1779 def debugindex(ui, repo, file_ = None, **opts):
1778 """dump the contents of an index file"""
1780 """dump the contents of an index file"""
1779 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1781 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1780 format = opts.get('format', 0)
1782 format = opts.get('format', 0)
1781 if format not in (0, 1):
1783 if format not in (0, 1):
1782 raise util.Abort(_("unknown format %d") % format)
1784 raise util.Abort(_("unknown format %d") % format)
1783
1785
1784 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1786 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1785 if generaldelta:
1787 if generaldelta:
1786 basehdr = ' delta'
1788 basehdr = ' delta'
1787 else:
1789 else:
1788 basehdr = ' base'
1790 basehdr = ' base'
1789
1791
1790 if format == 0:
1792 if format == 0:
1791 ui.write(" rev offset length " + basehdr + " linkrev"
1793 ui.write(" rev offset length " + basehdr + " linkrev"
1792 " nodeid p1 p2\n")
1794 " nodeid p1 p2\n")
1793 elif format == 1:
1795 elif format == 1:
1794 ui.write(" rev flag offset length"
1796 ui.write(" rev flag offset length"
1795 " size " + basehdr + " link p1 p2 nodeid\n")
1797 " size " + basehdr + " link p1 p2 nodeid\n")
1796
1798
1797 for i in r:
1799 for i in r:
1798 node = r.node(i)
1800 node = r.node(i)
1799 if generaldelta:
1801 if generaldelta:
1800 base = r.deltaparent(i)
1802 base = r.deltaparent(i)
1801 else:
1803 else:
1802 base = r.chainbase(i)
1804 base = r.chainbase(i)
1803 if format == 0:
1805 if format == 0:
1804 try:
1806 try:
1805 pp = r.parents(node)
1807 pp = r.parents(node)
1806 except:
1808 except:
1807 pp = [nullid, nullid]
1809 pp = [nullid, nullid]
1808 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1810 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1809 i, r.start(i), r.length(i), base, r.linkrev(i),
1811 i, r.start(i), r.length(i), base, r.linkrev(i),
1810 short(node), short(pp[0]), short(pp[1])))
1812 short(node), short(pp[0]), short(pp[1])))
1811 elif format == 1:
1813 elif format == 1:
1812 pr = r.parentrevs(i)
1814 pr = r.parentrevs(i)
1813 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1815 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1814 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1816 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1815 base, r.linkrev(i), pr[0], pr[1], short(node)))
1817 base, r.linkrev(i), pr[0], pr[1], short(node)))
1816
1818
1817 @command('debugindexdot', [], _('FILE'))
1819 @command('debugindexdot', [], _('FILE'))
1818 def debugindexdot(ui, repo, file_):
1820 def debugindexdot(ui, repo, file_):
1819 """dump an index DAG as a graphviz dot file"""
1821 """dump an index DAG as a graphviz dot file"""
1820 r = None
1822 r = None
1821 if repo:
1823 if repo:
1822 filelog = repo.file(file_)
1824 filelog = repo.file(file_)
1823 if len(filelog):
1825 if len(filelog):
1824 r = filelog
1826 r = filelog
1825 if not r:
1827 if not r:
1826 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1828 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1827 ui.write("digraph G {\n")
1829 ui.write("digraph G {\n")
1828 for i in r:
1830 for i in r:
1829 node = r.node(i)
1831 node = r.node(i)
1830 pp = r.parents(node)
1832 pp = r.parents(node)
1831 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1833 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1832 if pp[1] != nullid:
1834 if pp[1] != nullid:
1833 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1835 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1834 ui.write("}\n")
1836 ui.write("}\n")
1835
1837
1836 @command('debuginstall', [], '')
1838 @command('debuginstall', [], '')
1837 def debuginstall(ui):
1839 def debuginstall(ui):
1838 '''test Mercurial installation
1840 '''test Mercurial installation
1839
1841
1840 Returns 0 on success.
1842 Returns 0 on success.
1841 '''
1843 '''
1842
1844
1843 def writetemp(contents):
1845 def writetemp(contents):
1844 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1846 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1845 f = os.fdopen(fd, "wb")
1847 f = os.fdopen(fd, "wb")
1846 f.write(contents)
1848 f.write(contents)
1847 f.close()
1849 f.close()
1848 return name
1850 return name
1849
1851
1850 problems = 0
1852 problems = 0
1851
1853
1852 # encoding
1854 # encoding
1853 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1855 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1854 try:
1856 try:
1855 encoding.fromlocal("test")
1857 encoding.fromlocal("test")
1856 except util.Abort, inst:
1858 except util.Abort, inst:
1857 ui.write(" %s\n" % inst)
1859 ui.write(" %s\n" % inst)
1858 ui.write(_(" (check that your locale is properly set)\n"))
1860 ui.write(_(" (check that your locale is properly set)\n"))
1859 problems += 1
1861 problems += 1
1860
1862
1861 # compiled modules
1863 # compiled modules
1862 ui.status(_("Checking installed modules (%s)...\n")
1864 ui.status(_("Checking installed modules (%s)...\n")
1863 % os.path.dirname(__file__))
1865 % os.path.dirname(__file__))
1864 try:
1866 try:
1865 import bdiff, mpatch, base85, osutil
1867 import bdiff, mpatch, base85, osutil
1866 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1868 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1867 except Exception, inst:
1869 except Exception, inst:
1868 ui.write(" %s\n" % inst)
1870 ui.write(" %s\n" % inst)
1869 ui.write(_(" One or more extensions could not be found"))
1871 ui.write(_(" One or more extensions could not be found"))
1870 ui.write(_(" (check that you compiled the extensions)\n"))
1872 ui.write(_(" (check that you compiled the extensions)\n"))
1871 problems += 1
1873 problems += 1
1872
1874
1873 # templates
1875 # templates
1874 import templater
1876 import templater
1875 p = templater.templatepath()
1877 p = templater.templatepath()
1876 ui.status(_("Checking templates (%s)...\n") % ' '.join(p))
1878 ui.status(_("Checking templates (%s)...\n") % ' '.join(p))
1877 try:
1879 try:
1878 templater.templater(templater.templatepath("map-cmdline.default"))
1880 templater.templater(templater.templatepath("map-cmdline.default"))
1879 except Exception, inst:
1881 except Exception, inst:
1880 ui.write(" %s\n" % inst)
1882 ui.write(" %s\n" % inst)
1881 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1883 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1882 problems += 1
1884 problems += 1
1883
1885
1884 # editor
1886 # editor
1885 ui.status(_("Checking commit editor...\n"))
1887 ui.status(_("Checking commit editor...\n"))
1886 editor = ui.geteditor()
1888 editor = ui.geteditor()
1887 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1889 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1888 if not cmdpath:
1890 if not cmdpath:
1889 if editor == 'vi':
1891 if editor == 'vi':
1890 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1892 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1891 ui.write(_(" (specify a commit editor in your configuration"
1893 ui.write(_(" (specify a commit editor in your configuration"
1892 " file)\n"))
1894 " file)\n"))
1893 else:
1895 else:
1894 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1896 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1895 ui.write(_(" (specify a commit editor in your configuration"
1897 ui.write(_(" (specify a commit editor in your configuration"
1896 " file)\n"))
1898 " file)\n"))
1897 problems += 1
1899 problems += 1
1898
1900
1899 # check username
1901 # check username
1900 ui.status(_("Checking username...\n"))
1902 ui.status(_("Checking username...\n"))
1901 try:
1903 try:
1902 ui.username()
1904 ui.username()
1903 except util.Abort, e:
1905 except util.Abort, e:
1904 ui.write(" %s\n" % e)
1906 ui.write(" %s\n" % e)
1905 ui.write(_(" (specify a username in your configuration file)\n"))
1907 ui.write(_(" (specify a username in your configuration file)\n"))
1906 problems += 1
1908 problems += 1
1907
1909
1908 if not problems:
1910 if not problems:
1909 ui.status(_("No problems detected\n"))
1911 ui.status(_("No problems detected\n"))
1910 else:
1912 else:
1911 ui.write(_("%s problems detected,"
1913 ui.write(_("%s problems detected,"
1912 " please check your install!\n") % problems)
1914 " please check your install!\n") % problems)
1913
1915
1914 return problems
1916 return problems
1915
1917
1916 @command('debugknown', [], _('REPO ID...'))
1918 @command('debugknown', [], _('REPO ID...'))
1917 def debugknown(ui, repopath, *ids, **opts):
1919 def debugknown(ui, repopath, *ids, **opts):
1918 """test whether node ids are known to a repo
1920 """test whether node ids are known to a repo
1919
1921
1920 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1922 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1921 indicating unknown/known.
1923 indicating unknown/known.
1922 """
1924 """
1923 repo = hg.peer(ui, opts, repopath)
1925 repo = hg.peer(ui, opts, repopath)
1924 if not repo.capable('known'):
1926 if not repo.capable('known'):
1925 raise util.Abort("known() not supported by target repository")
1927 raise util.Abort("known() not supported by target repository")
1926 flags = repo.known([bin(s) for s in ids])
1928 flags = repo.known([bin(s) for s in ids])
1927 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1929 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1928
1930
1929 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
1931 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
1930 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1932 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1931 '''access the pushkey key/value protocol
1933 '''access the pushkey key/value protocol
1932
1934
1933 With two args, list the keys in the given namespace.
1935 With two args, list the keys in the given namespace.
1934
1936
1935 With five args, set a key to new if it currently is set to old.
1937 With five args, set a key to new if it currently is set to old.
1936 Reports success or failure.
1938 Reports success or failure.
1937 '''
1939 '''
1938
1940
1939 target = hg.peer(ui, {}, repopath)
1941 target = hg.peer(ui, {}, repopath)
1940 if keyinfo:
1942 if keyinfo:
1941 key, old, new = keyinfo
1943 key, old, new = keyinfo
1942 r = target.pushkey(namespace, key, old, new)
1944 r = target.pushkey(namespace, key, old, new)
1943 ui.status(str(r) + '\n')
1945 ui.status(str(r) + '\n')
1944 return not r
1946 return not r
1945 else:
1947 else:
1946 for k, v in target.listkeys(namespace).iteritems():
1948 for k, v in target.listkeys(namespace).iteritems():
1947 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1949 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1948 v.encode('string-escape')))
1950 v.encode('string-escape')))
1949
1951
1950 @command('debugrebuildstate',
1952 @command('debugrebuildstate',
1951 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
1953 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
1952 _('[-r REV] [REV]'))
1954 _('[-r REV] [REV]'))
1953 def debugrebuildstate(ui, repo, rev="tip"):
1955 def debugrebuildstate(ui, repo, rev="tip"):
1954 """rebuild the dirstate as it would look like for the given revision"""
1956 """rebuild the dirstate as it would look like for the given revision"""
1955 ctx = scmutil.revsingle(repo, rev)
1957 ctx = scmutil.revsingle(repo, rev)
1956 wlock = repo.wlock()
1958 wlock = repo.wlock()
1957 try:
1959 try:
1958 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1960 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1959 finally:
1961 finally:
1960 wlock.release()
1962 wlock.release()
1961
1963
1962 @command('debugrename',
1964 @command('debugrename',
1963 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1965 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1964 _('[-r REV] FILE'))
1966 _('[-r REV] FILE'))
1965 def debugrename(ui, repo, file1, *pats, **opts):
1967 def debugrename(ui, repo, file1, *pats, **opts):
1966 """dump rename information"""
1968 """dump rename information"""
1967
1969
1968 ctx = scmutil.revsingle(repo, opts.get('rev'))
1970 ctx = scmutil.revsingle(repo, opts.get('rev'))
1969 m = scmutil.match(ctx, (file1,) + pats, opts)
1971 m = scmutil.match(ctx, (file1,) + pats, opts)
1970 for abs in ctx.walk(m):
1972 for abs in ctx.walk(m):
1971 fctx = ctx[abs]
1973 fctx = ctx[abs]
1972 o = fctx.filelog().renamed(fctx.filenode())
1974 o = fctx.filelog().renamed(fctx.filenode())
1973 rel = m.rel(abs)
1975 rel = m.rel(abs)
1974 if o:
1976 if o:
1975 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1977 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1976 else:
1978 else:
1977 ui.write(_("%s not renamed\n") % rel)
1979 ui.write(_("%s not renamed\n") % rel)
1978
1980
1979 @command('debugrevlog',
1981 @command('debugrevlog',
1980 [('c', 'changelog', False, _('open changelog')),
1982 [('c', 'changelog', False, _('open changelog')),
1981 ('m', 'manifest', False, _('open manifest')),
1983 ('m', 'manifest', False, _('open manifest')),
1982 ('d', 'dump', False, _('dump index data'))],
1984 ('d', 'dump', False, _('dump index data'))],
1983 _('-c|-m|FILE'))
1985 _('-c|-m|FILE'))
1984 def debugrevlog(ui, repo, file_ = None, **opts):
1986 def debugrevlog(ui, repo, file_ = None, **opts):
1985 """show data and statistics about a revlog"""
1987 """show data and statistics about a revlog"""
1986 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1988 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1987
1989
1988 if opts.get("dump"):
1990 if opts.get("dump"):
1989 numrevs = len(r)
1991 numrevs = len(r)
1990 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
1992 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
1991 " rawsize totalsize compression heads\n")
1993 " rawsize totalsize compression heads\n")
1992 ts = 0
1994 ts = 0
1993 heads = set()
1995 heads = set()
1994 for rev in xrange(numrevs):
1996 for rev in xrange(numrevs):
1995 dbase = r.deltaparent(rev)
1997 dbase = r.deltaparent(rev)
1996 if dbase == -1:
1998 if dbase == -1:
1997 dbase = rev
1999 dbase = rev
1998 cbase = r.chainbase(rev)
2000 cbase = r.chainbase(rev)
1999 p1, p2 = r.parentrevs(rev)
2001 p1, p2 = r.parentrevs(rev)
2000 rs = r.rawsize(rev)
2002 rs = r.rawsize(rev)
2001 ts = ts + rs
2003 ts = ts + rs
2002 heads -= set(r.parentrevs(rev))
2004 heads -= set(r.parentrevs(rev))
2003 heads.add(rev)
2005 heads.add(rev)
2004 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2006 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2005 (rev, p1, p2, r.start(rev), r.end(rev),
2007 (rev, p1, p2, r.start(rev), r.end(rev),
2006 r.start(dbase), r.start(cbase),
2008 r.start(dbase), r.start(cbase),
2007 r.start(p1), r.start(p2),
2009 r.start(p1), r.start(p2),
2008 rs, ts, ts / r.end(rev), len(heads)))
2010 rs, ts, ts / r.end(rev), len(heads)))
2009 return 0
2011 return 0
2010
2012
2011 v = r.version
2013 v = r.version
2012 format = v & 0xFFFF
2014 format = v & 0xFFFF
2013 flags = []
2015 flags = []
2014 gdelta = False
2016 gdelta = False
2015 if v & revlog.REVLOGNGINLINEDATA:
2017 if v & revlog.REVLOGNGINLINEDATA:
2016 flags.append('inline')
2018 flags.append('inline')
2017 if v & revlog.REVLOGGENERALDELTA:
2019 if v & revlog.REVLOGGENERALDELTA:
2018 gdelta = True
2020 gdelta = True
2019 flags.append('generaldelta')
2021 flags.append('generaldelta')
2020 if not flags:
2022 if not flags:
2021 flags = ['(none)']
2023 flags = ['(none)']
2022
2024
2023 nummerges = 0
2025 nummerges = 0
2024 numfull = 0
2026 numfull = 0
2025 numprev = 0
2027 numprev = 0
2026 nump1 = 0
2028 nump1 = 0
2027 nump2 = 0
2029 nump2 = 0
2028 numother = 0
2030 numother = 0
2029 nump1prev = 0
2031 nump1prev = 0
2030 nump2prev = 0
2032 nump2prev = 0
2031 chainlengths = []
2033 chainlengths = []
2032
2034
2033 datasize = [None, 0, 0L]
2035 datasize = [None, 0, 0L]
2034 fullsize = [None, 0, 0L]
2036 fullsize = [None, 0, 0L]
2035 deltasize = [None, 0, 0L]
2037 deltasize = [None, 0, 0L]
2036
2038
2037 def addsize(size, l):
2039 def addsize(size, l):
2038 if l[0] is None or size < l[0]:
2040 if l[0] is None or size < l[0]:
2039 l[0] = size
2041 l[0] = size
2040 if size > l[1]:
2042 if size > l[1]:
2041 l[1] = size
2043 l[1] = size
2042 l[2] += size
2044 l[2] += size
2043
2045
2044 numrevs = len(r)
2046 numrevs = len(r)
2045 for rev in xrange(numrevs):
2047 for rev in xrange(numrevs):
2046 p1, p2 = r.parentrevs(rev)
2048 p1, p2 = r.parentrevs(rev)
2047 delta = r.deltaparent(rev)
2049 delta = r.deltaparent(rev)
2048 if format > 0:
2050 if format > 0:
2049 addsize(r.rawsize(rev), datasize)
2051 addsize(r.rawsize(rev), datasize)
2050 if p2 != nullrev:
2052 if p2 != nullrev:
2051 nummerges += 1
2053 nummerges += 1
2052 size = r.length(rev)
2054 size = r.length(rev)
2053 if delta == nullrev:
2055 if delta == nullrev:
2054 chainlengths.append(0)
2056 chainlengths.append(0)
2055 numfull += 1
2057 numfull += 1
2056 addsize(size, fullsize)
2058 addsize(size, fullsize)
2057 else:
2059 else:
2058 chainlengths.append(chainlengths[delta] + 1)
2060 chainlengths.append(chainlengths[delta] + 1)
2059 addsize(size, deltasize)
2061 addsize(size, deltasize)
2060 if delta == rev - 1:
2062 if delta == rev - 1:
2061 numprev += 1
2063 numprev += 1
2062 if delta == p1:
2064 if delta == p1:
2063 nump1prev += 1
2065 nump1prev += 1
2064 elif delta == p2:
2066 elif delta == p2:
2065 nump2prev += 1
2067 nump2prev += 1
2066 elif delta == p1:
2068 elif delta == p1:
2067 nump1 += 1
2069 nump1 += 1
2068 elif delta == p2:
2070 elif delta == p2:
2069 nump2 += 1
2071 nump2 += 1
2070 elif delta != nullrev:
2072 elif delta != nullrev:
2071 numother += 1
2073 numother += 1
2072
2074
2073 numdeltas = numrevs - numfull
2075 numdeltas = numrevs - numfull
2074 numoprev = numprev - nump1prev - nump2prev
2076 numoprev = numprev - nump1prev - nump2prev
2075 totalrawsize = datasize[2]
2077 totalrawsize = datasize[2]
2076 datasize[2] /= numrevs
2078 datasize[2] /= numrevs
2077 fulltotal = fullsize[2]
2079 fulltotal = fullsize[2]
2078 fullsize[2] /= numfull
2080 fullsize[2] /= numfull
2079 deltatotal = deltasize[2]
2081 deltatotal = deltasize[2]
2080 deltasize[2] /= numrevs - numfull
2082 deltasize[2] /= numrevs - numfull
2081 totalsize = fulltotal + deltatotal
2083 totalsize = fulltotal + deltatotal
2082 avgchainlen = sum(chainlengths) / numrevs
2084 avgchainlen = sum(chainlengths) / numrevs
2083 compratio = totalrawsize / totalsize
2085 compratio = totalrawsize / totalsize
2084
2086
2085 basedfmtstr = '%%%dd\n'
2087 basedfmtstr = '%%%dd\n'
2086 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2088 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2087
2089
2088 def dfmtstr(max):
2090 def dfmtstr(max):
2089 return basedfmtstr % len(str(max))
2091 return basedfmtstr % len(str(max))
2090 def pcfmtstr(max, padding=0):
2092 def pcfmtstr(max, padding=0):
2091 return basepcfmtstr % (len(str(max)), ' ' * padding)
2093 return basepcfmtstr % (len(str(max)), ' ' * padding)
2092
2094
2093 def pcfmt(value, total):
2095 def pcfmt(value, total):
2094 return (value, 100 * float(value) / total)
2096 return (value, 100 * float(value) / total)
2095
2097
2096 ui.write('format : %d\n' % format)
2098 ui.write('format : %d\n' % format)
2097 ui.write('flags : %s\n' % ', '.join(flags))
2099 ui.write('flags : %s\n' % ', '.join(flags))
2098
2100
2099 ui.write('\n')
2101 ui.write('\n')
2100 fmt = pcfmtstr(totalsize)
2102 fmt = pcfmtstr(totalsize)
2101 fmt2 = dfmtstr(totalsize)
2103 fmt2 = dfmtstr(totalsize)
2102 ui.write('revisions : ' + fmt2 % numrevs)
2104 ui.write('revisions : ' + fmt2 % numrevs)
2103 ui.write(' merges : ' + fmt % pcfmt(nummerges, numrevs))
2105 ui.write(' merges : ' + fmt % pcfmt(nummerges, numrevs))
2104 ui.write(' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs))
2106 ui.write(' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs))
2105 ui.write('revisions : ' + fmt2 % numrevs)
2107 ui.write('revisions : ' + fmt2 % numrevs)
2106 ui.write(' full : ' + fmt % pcfmt(numfull, numrevs))
2108 ui.write(' full : ' + fmt % pcfmt(numfull, numrevs))
2107 ui.write(' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2109 ui.write(' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2108 ui.write('revision size : ' + fmt2 % totalsize)
2110 ui.write('revision size : ' + fmt2 % totalsize)
2109 ui.write(' full : ' + fmt % pcfmt(fulltotal, totalsize))
2111 ui.write(' full : ' + fmt % pcfmt(fulltotal, totalsize))
2110 ui.write(' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2112 ui.write(' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2111
2113
2112 ui.write('\n')
2114 ui.write('\n')
2113 fmt = dfmtstr(max(avgchainlen, compratio))
2115 fmt = dfmtstr(max(avgchainlen, compratio))
2114 ui.write('avg chain length : ' + fmt % avgchainlen)
2116 ui.write('avg chain length : ' + fmt % avgchainlen)
2115 ui.write('compression ratio : ' + fmt % compratio)
2117 ui.write('compression ratio : ' + fmt % compratio)
2116
2118
2117 if format > 0:
2119 if format > 0:
2118 ui.write('\n')
2120 ui.write('\n')
2119 ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
2121 ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
2120 % tuple(datasize))
2122 % tuple(datasize))
2121 ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
2123 ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
2122 % tuple(fullsize))
2124 % tuple(fullsize))
2123 ui.write('delta size (min/max/avg) : %d / %d / %d\n'
2125 ui.write('delta size (min/max/avg) : %d / %d / %d\n'
2124 % tuple(deltasize))
2126 % tuple(deltasize))
2125
2127
2126 if numdeltas > 0:
2128 if numdeltas > 0:
2127 ui.write('\n')
2129 ui.write('\n')
2128 fmt = pcfmtstr(numdeltas)
2130 fmt = pcfmtstr(numdeltas)
2129 fmt2 = pcfmtstr(numdeltas, 4)
2131 fmt2 = pcfmtstr(numdeltas, 4)
2130 ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
2132 ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
2131 if numprev > 0:
2133 if numprev > 0:
2132 ui.write(' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev))
2134 ui.write(' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev))
2133 ui.write(' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev))
2135 ui.write(' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev))
2134 ui.write(' other : ' + fmt2 % pcfmt(numoprev, numprev))
2136 ui.write(' other : ' + fmt2 % pcfmt(numoprev, numprev))
2135 if gdelta:
2137 if gdelta:
2136 ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
2138 ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
2137 ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
2139 ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
2138 ui.write('deltas against other : ' + fmt % pcfmt(numother, numdeltas))
2140 ui.write('deltas against other : ' + fmt % pcfmt(numother, numdeltas))
2139
2141
2140 @command('debugrevspec', [], ('REVSPEC'))
2142 @command('debugrevspec', [], ('REVSPEC'))
2141 def debugrevspec(ui, repo, expr):
2143 def debugrevspec(ui, repo, expr):
2142 '''parse and apply a revision specification'''
2144 '''parse and apply a revision specification'''
2143 if ui.verbose:
2145 if ui.verbose:
2144 tree = revset.parse(expr)[0]
2146 tree = revset.parse(expr)[0]
2145 ui.note(tree, "\n")
2147 ui.note(tree, "\n")
2146 newtree = revset.findaliases(ui, tree)
2148 newtree = revset.findaliases(ui, tree)
2147 if newtree != tree:
2149 if newtree != tree:
2148 ui.note(newtree, "\n")
2150 ui.note(newtree, "\n")
2149 func = revset.match(ui, expr)
2151 func = revset.match(ui, expr)
2150 for c in func(repo, range(len(repo))):
2152 for c in func(repo, range(len(repo))):
2151 ui.write("%s\n" % c)
2153 ui.write("%s\n" % c)
2152
2154
2153 @command('debugsetparents', [], _('REV1 [REV2]'))
2155 @command('debugsetparents', [], _('REV1 [REV2]'))
2154 def debugsetparents(ui, repo, rev1, rev2=None):
2156 def debugsetparents(ui, repo, rev1, rev2=None):
2155 """manually set the parents of the current working directory
2157 """manually set the parents of the current working directory
2156
2158
2157 This is useful for writing repository conversion tools, but should
2159 This is useful for writing repository conversion tools, but should
2158 be used with care.
2160 be used with care.
2159
2161
2160 Returns 0 on success.
2162 Returns 0 on success.
2161 """
2163 """
2162
2164
2163 r1 = scmutil.revsingle(repo, rev1).node()
2165 r1 = scmutil.revsingle(repo, rev1).node()
2164 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2166 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2165
2167
2166 wlock = repo.wlock()
2168 wlock = repo.wlock()
2167 try:
2169 try:
2168 repo.dirstate.setparents(r1, r2)
2170 repo.dirstate.setparents(r1, r2)
2169 finally:
2171 finally:
2170 wlock.release()
2172 wlock.release()
2171
2173
2172 @command('debugstate',
2174 @command('debugstate',
2173 [('', 'nodates', None, _('do not display the saved mtime')),
2175 [('', 'nodates', None, _('do not display the saved mtime')),
2174 ('', 'datesort', None, _('sort by saved mtime'))],
2176 ('', 'datesort', None, _('sort by saved mtime'))],
2175 _('[OPTION]...'))
2177 _('[OPTION]...'))
2176 def debugstate(ui, repo, nodates=None, datesort=None):
2178 def debugstate(ui, repo, nodates=None, datesort=None):
2177 """show the contents of the current dirstate"""
2179 """show the contents of the current dirstate"""
2178 timestr = ""
2180 timestr = ""
2179 showdate = not nodates
2181 showdate = not nodates
2180 if datesort:
2182 if datesort:
2181 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2183 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2182 else:
2184 else:
2183 keyfunc = None # sort by filename
2185 keyfunc = None # sort by filename
2184 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2186 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2185 if showdate:
2187 if showdate:
2186 if ent[3] == -1:
2188 if ent[3] == -1:
2187 # Pad or slice to locale representation
2189 # Pad or slice to locale representation
2188 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2190 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2189 time.localtime(0)))
2191 time.localtime(0)))
2190 timestr = 'unset'
2192 timestr = 'unset'
2191 timestr = (timestr[:locale_len] +
2193 timestr = (timestr[:locale_len] +
2192 ' ' * (locale_len - len(timestr)))
2194 ' ' * (locale_len - len(timestr)))
2193 else:
2195 else:
2194 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2196 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2195 time.localtime(ent[3]))
2197 time.localtime(ent[3]))
2196 if ent[1] & 020000:
2198 if ent[1] & 020000:
2197 mode = 'lnk'
2199 mode = 'lnk'
2198 else:
2200 else:
2199 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2201 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2200 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2202 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2201 for f in repo.dirstate.copies():
2203 for f in repo.dirstate.copies():
2202 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2204 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2203
2205
2204 @command('debugsub',
2206 @command('debugsub',
2205 [('r', 'rev', '',
2207 [('r', 'rev', '',
2206 _('revision to check'), _('REV'))],
2208 _('revision to check'), _('REV'))],
2207 _('[-r REV] [REV]'))
2209 _('[-r REV] [REV]'))
2208 def debugsub(ui, repo, rev=None):
2210 def debugsub(ui, repo, rev=None):
2209 ctx = scmutil.revsingle(repo, rev, None)
2211 ctx = scmutil.revsingle(repo, rev, None)
2210 for k, v in sorted(ctx.substate.items()):
2212 for k, v in sorted(ctx.substate.items()):
2211 ui.write('path %s\n' % k)
2213 ui.write('path %s\n' % k)
2212 ui.write(' source %s\n' % v[0])
2214 ui.write(' source %s\n' % v[0])
2213 ui.write(' revision %s\n' % v[1])
2215 ui.write(' revision %s\n' % v[1])
2214
2216
2215 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2217 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2216 def debugwalk(ui, repo, *pats, **opts):
2218 def debugwalk(ui, repo, *pats, **opts):
2217 """show how files match on given patterns"""
2219 """show how files match on given patterns"""
2218 m = scmutil.match(repo[None], pats, opts)
2220 m = scmutil.match(repo[None], pats, opts)
2219 items = list(repo.walk(m))
2221 items = list(repo.walk(m))
2220 if not items:
2222 if not items:
2221 return
2223 return
2222 fmt = 'f %%-%ds %%-%ds %%s' % (
2224 fmt = 'f %%-%ds %%-%ds %%s' % (
2223 max([len(abs) for abs in items]),
2225 max([len(abs) for abs in items]),
2224 max([len(m.rel(abs)) for abs in items]))
2226 max([len(m.rel(abs)) for abs in items]))
2225 for abs in items:
2227 for abs in items:
2226 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
2228 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
2227 ui.write("%s\n" % line.rstrip())
2229 ui.write("%s\n" % line.rstrip())
2228
2230
2229 @command('debugwireargs',
2231 @command('debugwireargs',
2230 [('', 'three', '', 'three'),
2232 [('', 'three', '', 'three'),
2231 ('', 'four', '', 'four'),
2233 ('', 'four', '', 'four'),
2232 ('', 'five', '', 'five'),
2234 ('', 'five', '', 'five'),
2233 ] + remoteopts,
2235 ] + remoteopts,
2234 _('REPO [OPTIONS]... [ONE [TWO]]'))
2236 _('REPO [OPTIONS]... [ONE [TWO]]'))
2235 def debugwireargs(ui, repopath, *vals, **opts):
2237 def debugwireargs(ui, repopath, *vals, **opts):
2236 repo = hg.peer(ui, opts, repopath)
2238 repo = hg.peer(ui, opts, repopath)
2237 for opt in remoteopts:
2239 for opt in remoteopts:
2238 del opts[opt[1]]
2240 del opts[opt[1]]
2239 args = {}
2241 args = {}
2240 for k, v in opts.iteritems():
2242 for k, v in opts.iteritems():
2241 if v:
2243 if v:
2242 args[k] = v
2244 args[k] = v
2243 # run twice to check that we don't mess up the stream for the next command
2245 # run twice to check that we don't mess up the stream for the next command
2244 res1 = repo.debugwireargs(*vals, **args)
2246 res1 = repo.debugwireargs(*vals, **args)
2245 res2 = repo.debugwireargs(*vals, **args)
2247 res2 = repo.debugwireargs(*vals, **args)
2246 ui.write("%s\n" % res1)
2248 ui.write("%s\n" % res1)
2247 if res1 != res2:
2249 if res1 != res2:
2248 ui.warn("%s\n" % res2)
2250 ui.warn("%s\n" % res2)
2249
2251
2250 @command('^diff',
2252 @command('^diff',
2251 [('r', 'rev', [], _('revision'), _('REV')),
2253 [('r', 'rev', [], _('revision'), _('REV')),
2252 ('c', 'change', '', _('change made by revision'), _('REV'))
2254 ('c', 'change', '', _('change made by revision'), _('REV'))
2253 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2255 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2254 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2256 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2255 def diff(ui, repo, *pats, **opts):
2257 def diff(ui, repo, *pats, **opts):
2256 """diff repository (or selected files)
2258 """diff repository (or selected files)
2257
2259
2258 Show differences between revisions for the specified files.
2260 Show differences between revisions for the specified files.
2259
2261
2260 Differences between files are shown using the unified diff format.
2262 Differences between files are shown using the unified diff format.
2261
2263
2262 .. note::
2264 .. note::
2263 diff may generate unexpected results for merges, as it will
2265 diff may generate unexpected results for merges, as it will
2264 default to comparing against the working directory's first
2266 default to comparing against the working directory's first
2265 parent changeset if no revisions are specified.
2267 parent changeset if no revisions are specified.
2266
2268
2267 When two revision arguments are given, then changes are shown
2269 When two revision arguments are given, then changes are shown
2268 between those revisions. If only one revision is specified then
2270 between those revisions. If only one revision is specified then
2269 that revision is compared to the working directory, and, when no
2271 that revision is compared to the working directory, and, when no
2270 revisions are specified, the working directory files are compared
2272 revisions are specified, the working directory files are compared
2271 to its parent.
2273 to its parent.
2272
2274
2273 Alternatively you can specify -c/--change with a revision to see
2275 Alternatively you can specify -c/--change with a revision to see
2274 the changes in that changeset relative to its first parent.
2276 the changes in that changeset relative to its first parent.
2275
2277
2276 Without the -a/--text option, diff will avoid generating diffs of
2278 Without the -a/--text option, diff will avoid generating diffs of
2277 files it detects as binary. With -a, diff will generate a diff
2279 files it detects as binary. With -a, diff will generate a diff
2278 anyway, probably with undesirable results.
2280 anyway, probably with undesirable results.
2279
2281
2280 Use the -g/--git option to generate diffs in the git extended diff
2282 Use the -g/--git option to generate diffs in the git extended diff
2281 format. For more information, read :hg:`help diffs`.
2283 format. For more information, read :hg:`help diffs`.
2282
2284
2283 .. container:: verbose
2285 .. container:: verbose
2284
2286
2285 Examples:
2287 Examples:
2286
2288
2287 - compare a file in the current working directory to its parent::
2289 - compare a file in the current working directory to its parent::
2288
2290
2289 hg diff foo.c
2291 hg diff foo.c
2290
2292
2291 - compare two historical versions of a directory, with rename info::
2293 - compare two historical versions of a directory, with rename info::
2292
2294
2293 hg diff --git -r 1.0:1.2 lib/
2295 hg diff --git -r 1.0:1.2 lib/
2294
2296
2295 - get change stats relative to the last change on some date::
2297 - get change stats relative to the last change on some date::
2296
2298
2297 hg diff --stat -r "date('may 2')"
2299 hg diff --stat -r "date('may 2')"
2298
2300
2299 - diff all newly-added files that contain a keyword::
2301 - diff all newly-added files that contain a keyword::
2300
2302
2301 hg diff "set:added() and grep(GNU)"
2303 hg diff "set:added() and grep(GNU)"
2302
2304
2303 - compare a revision and its parents::
2305 - compare a revision and its parents::
2304
2306
2305 hg diff -c 9353 # compare against first parent
2307 hg diff -c 9353 # compare against first parent
2306 hg diff -r 9353^:9353 # same using revset syntax
2308 hg diff -r 9353^:9353 # same using revset syntax
2307 hg diff -r 9353^2:9353 # compare against the second parent
2309 hg diff -r 9353^2:9353 # compare against the second parent
2308
2310
2309 Returns 0 on success.
2311 Returns 0 on success.
2310 """
2312 """
2311
2313
2312 revs = opts.get('rev')
2314 revs = opts.get('rev')
2313 change = opts.get('change')
2315 change = opts.get('change')
2314 stat = opts.get('stat')
2316 stat = opts.get('stat')
2315 reverse = opts.get('reverse')
2317 reverse = opts.get('reverse')
2316
2318
2317 if revs and change:
2319 if revs and change:
2318 msg = _('cannot specify --rev and --change at the same time')
2320 msg = _('cannot specify --rev and --change at the same time')
2319 raise util.Abort(msg)
2321 raise util.Abort(msg)
2320 elif change:
2322 elif change:
2321 node2 = scmutil.revsingle(repo, change, None).node()
2323 node2 = scmutil.revsingle(repo, change, None).node()
2322 node1 = repo[node2].p1().node()
2324 node1 = repo[node2].p1().node()
2323 else:
2325 else:
2324 node1, node2 = scmutil.revpair(repo, revs)
2326 node1, node2 = scmutil.revpair(repo, revs)
2325
2327
2326 if reverse:
2328 if reverse:
2327 node1, node2 = node2, node1
2329 node1, node2 = node2, node1
2328
2330
2329 diffopts = patch.diffopts(ui, opts)
2331 diffopts = patch.diffopts(ui, opts)
2330 m = scmutil.match(repo[node2], pats, opts)
2332 m = scmutil.match(repo[node2], pats, opts)
2331 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2333 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2332 listsubrepos=opts.get('subrepos'))
2334 listsubrepos=opts.get('subrepos'))
2333
2335
2334 @command('^export',
2336 @command('^export',
2335 [('o', 'output', '',
2337 [('o', 'output', '',
2336 _('print output to file with formatted name'), _('FORMAT')),
2338 _('print output to file with formatted name'), _('FORMAT')),
2337 ('', 'switch-parent', None, _('diff against the second parent')),
2339 ('', 'switch-parent', None, _('diff against the second parent')),
2338 ('r', 'rev', [], _('revisions to export'), _('REV')),
2340 ('r', 'rev', [], _('revisions to export'), _('REV')),
2339 ] + diffopts,
2341 ] + diffopts,
2340 _('[OPTION]... [-o OUTFILESPEC] REV...'))
2342 _('[OPTION]... [-o OUTFILESPEC] REV...'))
2341 def export(ui, repo, *changesets, **opts):
2343 def export(ui, repo, *changesets, **opts):
2342 """dump the header and diffs for one or more changesets
2344 """dump the header and diffs for one or more changesets
2343
2345
2344 Print the changeset header and diffs for one or more revisions.
2346 Print the changeset header and diffs for one or more revisions.
2345
2347
2346 The information shown in the changeset header is: author, date,
2348 The information shown in the changeset header is: author, date,
2347 branch name (if non-default), changeset hash, parent(s) and commit
2349 branch name (if non-default), changeset hash, parent(s) and commit
2348 comment.
2350 comment.
2349
2351
2350 .. note::
2352 .. note::
2351 export may generate unexpected diff output for merge
2353 export may generate unexpected diff output for merge
2352 changesets, as it will compare the merge changeset against its
2354 changesets, as it will compare the merge changeset against its
2353 first parent only.
2355 first parent only.
2354
2356
2355 Output may be to a file, in which case the name of the file is
2357 Output may be to a file, in which case the name of the file is
2356 given using a format string. The formatting rules are as follows:
2358 given using a format string. The formatting rules are as follows:
2357
2359
2358 :``%%``: literal "%" character
2360 :``%%``: literal "%" character
2359 :``%H``: changeset hash (40 hexadecimal digits)
2361 :``%H``: changeset hash (40 hexadecimal digits)
2360 :``%N``: number of patches being generated
2362 :``%N``: number of patches being generated
2361 :``%R``: changeset revision number
2363 :``%R``: changeset revision number
2362 :``%b``: basename of the exporting repository
2364 :``%b``: basename of the exporting repository
2363 :``%h``: short-form changeset hash (12 hexadecimal digits)
2365 :``%h``: short-form changeset hash (12 hexadecimal digits)
2364 :``%m``: first line of the commit message (only alphanumeric characters)
2366 :``%m``: first line of the commit message (only alphanumeric characters)
2365 :``%n``: zero-padded sequence number, starting at 1
2367 :``%n``: zero-padded sequence number, starting at 1
2366 :``%r``: zero-padded changeset revision number
2368 :``%r``: zero-padded changeset revision number
2367
2369
2368 Without the -a/--text option, export will avoid generating diffs
2370 Without the -a/--text option, export will avoid generating diffs
2369 of files it detects as binary. With -a, export will generate a
2371 of files it detects as binary. With -a, export will generate a
2370 diff anyway, probably with undesirable results.
2372 diff anyway, probably with undesirable results.
2371
2373
2372 Use the -g/--git option to generate diffs in the git extended diff
2374 Use the -g/--git option to generate diffs in the git extended diff
2373 format. See :hg:`help diffs` for more information.
2375 format. See :hg:`help diffs` for more information.
2374
2376
2375 With the --switch-parent option, the diff will be against the
2377 With the --switch-parent option, the diff will be against the
2376 second parent. It can be useful to review a merge.
2378 second parent. It can be useful to review a merge.
2377
2379
2378 .. container:: verbose
2380 .. container:: verbose
2379
2381
2380 Examples:
2382 Examples:
2381
2383
2382 - use export and import to transplant a bugfix to the current
2384 - use export and import to transplant a bugfix to the current
2383 branch::
2385 branch::
2384
2386
2385 hg export -r 9353 | hg import -
2387 hg export -r 9353 | hg import -
2386
2388
2387 - export all the changesets between two revisions to a file with
2389 - export all the changesets between two revisions to a file with
2388 rename information::
2390 rename information::
2389
2391
2390 hg export --git -r 123:150 > changes.txt
2392 hg export --git -r 123:150 > changes.txt
2391
2393
2392 - split outgoing changes into a series of patches with
2394 - split outgoing changes into a series of patches with
2393 descriptive names::
2395 descriptive names::
2394
2396
2395 hg export -r "outgoing()" -o "%n-%m.patch"
2397 hg export -r "outgoing()" -o "%n-%m.patch"
2396
2398
2397 Returns 0 on success.
2399 Returns 0 on success.
2398 """
2400 """
2399 changesets += tuple(opts.get('rev', []))
2401 changesets += tuple(opts.get('rev', []))
2400 if not changesets:
2402 if not changesets:
2401 raise util.Abort(_("export requires at least one changeset"))
2403 raise util.Abort(_("export requires at least one changeset"))
2402 revs = scmutil.revrange(repo, changesets)
2404 revs = scmutil.revrange(repo, changesets)
2403 if len(revs) > 1:
2405 if len(revs) > 1:
2404 ui.note(_('exporting patches:\n'))
2406 ui.note(_('exporting patches:\n'))
2405 else:
2407 else:
2406 ui.note(_('exporting patch:\n'))
2408 ui.note(_('exporting patch:\n'))
2407 cmdutil.export(repo, revs, template=opts.get('output'),
2409 cmdutil.export(repo, revs, template=opts.get('output'),
2408 switch_parent=opts.get('switch_parent'),
2410 switch_parent=opts.get('switch_parent'),
2409 opts=patch.diffopts(ui, opts))
2411 opts=patch.diffopts(ui, opts))
2410
2412
2411 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2413 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2412 def forget(ui, repo, *pats, **opts):
2414 def forget(ui, repo, *pats, **opts):
2413 """forget the specified files on the next commit
2415 """forget the specified files on the next commit
2414
2416
2415 Mark the specified files so they will no longer be tracked
2417 Mark the specified files so they will no longer be tracked
2416 after the next commit.
2418 after the next commit.
2417
2419
2418 This only removes files from the current branch, not from the
2420 This only removes files from the current branch, not from the
2419 entire project history, and it does not delete them from the
2421 entire project history, and it does not delete them from the
2420 working directory.
2422 working directory.
2421
2423
2422 To undo a forget before the next commit, see :hg:`add`.
2424 To undo a forget before the next commit, see :hg:`add`.
2423
2425
2424 .. container:: verbose
2426 .. container:: verbose
2425
2427
2426 Examples:
2428 Examples:
2427
2429
2428 - forget newly-added binary files::
2430 - forget newly-added binary files::
2429
2431
2430 hg forget "set:added() and binary()"
2432 hg forget "set:added() and binary()"
2431
2433
2432 - forget files that would be excluded by .hgignore::
2434 - forget files that would be excluded by .hgignore::
2433
2435
2434 hg forget "set:hgignore()"
2436 hg forget "set:hgignore()"
2435
2437
2436 Returns 0 on success.
2438 Returns 0 on success.
2437 """
2439 """
2438
2440
2439 if not pats:
2441 if not pats:
2440 raise util.Abort(_('no files specified'))
2442 raise util.Abort(_('no files specified'))
2441
2443
2442 wctx = repo[None]
2444 wctx = repo[None]
2443 m = scmutil.match(wctx, pats, opts)
2445 m = scmutil.match(wctx, pats, opts)
2444 s = repo.status(match=m, clean=True)
2446 s = repo.status(match=m, clean=True)
2445 forget = sorted(s[0] + s[1] + s[3] + s[6])
2447 forget = sorted(s[0] + s[1] + s[3] + s[6])
2446 subforget = {}
2448 subforget = {}
2447 errs = 0
2449 errs = 0
2448
2450
2449 for subpath in wctx.substate:
2451 for subpath in wctx.substate:
2450 sub = wctx.sub(subpath)
2452 sub = wctx.sub(subpath)
2451 try:
2453 try:
2452 submatch = matchmod.narrowmatcher(subpath, m)
2454 submatch = matchmod.narrowmatcher(subpath, m)
2453 for fsub in sub.walk(submatch):
2455 for fsub in sub.walk(submatch):
2454 if submatch.exact(fsub):
2456 if submatch.exact(fsub):
2455 subforget[subpath + '/' + fsub] = (fsub, sub)
2457 subforget[subpath + '/' + fsub] = (fsub, sub)
2456 except error.LookupError:
2458 except error.LookupError:
2457 ui.status(_("skipping missing subrepository: %s\n") % subpath)
2459 ui.status(_("skipping missing subrepository: %s\n") % subpath)
2458
2460
2459 for f in m.files():
2461 for f in m.files():
2460 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2462 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2461 if f not in subforget:
2463 if f not in subforget:
2462 if os.path.exists(m.rel(f)):
2464 if os.path.exists(m.rel(f)):
2463 ui.warn(_('not removing %s: file is already untracked\n')
2465 ui.warn(_('not removing %s: file is already untracked\n')
2464 % m.rel(f))
2466 % m.rel(f))
2465 errs = 1
2467 errs = 1
2466
2468
2467 for f in forget:
2469 for f in forget:
2468 if ui.verbose or not m.exact(f):
2470 if ui.verbose or not m.exact(f):
2469 ui.status(_('removing %s\n') % m.rel(f))
2471 ui.status(_('removing %s\n') % m.rel(f))
2470
2472
2471 if ui.verbose:
2473 if ui.verbose:
2472 for f in sorted(subforget.keys()):
2474 for f in sorted(subforget.keys()):
2473 ui.status(_('removing %s\n') % m.rel(f))
2475 ui.status(_('removing %s\n') % m.rel(f))
2474
2476
2475 wctx.forget(forget)
2477 wctx.forget(forget)
2476
2478
2477 for f in sorted(subforget.keys()):
2479 for f in sorted(subforget.keys()):
2478 fsub, sub = subforget[f]
2480 fsub, sub = subforget[f]
2479 sub.forget([fsub])
2481 sub.forget([fsub])
2480
2482
2481 return errs
2483 return errs
2482
2484
2483 @command(
2485 @command(
2484 'graft',
2486 'graft',
2485 [('c', 'continue', False, _('resume interrupted graft')),
2487 [('c', 'continue', False, _('resume interrupted graft')),
2486 ('e', 'edit', False, _('invoke editor on commit messages')),
2488 ('e', 'edit', False, _('invoke editor on commit messages')),
2487 ('D', 'currentdate', False,
2489 ('D', 'currentdate', False,
2488 _('record the current date as commit date')),
2490 _('record the current date as commit date')),
2489 ('U', 'currentuser', False,
2491 ('U', 'currentuser', False,
2490 _('record the current user as committer'), _('DATE'))]
2492 _('record the current user as committer'), _('DATE'))]
2491 + commitopts2 + mergetoolopts,
2493 + commitopts2 + mergetoolopts,
2492 _('[OPTION]... REVISION...'))
2494 _('[OPTION]... REVISION...'))
2493 def graft(ui, repo, *revs, **opts):
2495 def graft(ui, repo, *revs, **opts):
2494 '''copy changes from other branches onto the current branch
2496 '''copy changes from other branches onto the current branch
2495
2497
2496 This command uses Mercurial's merge logic to copy individual
2498 This command uses Mercurial's merge logic to copy individual
2497 changes from other branches without merging branches in the
2499 changes from other branches without merging branches in the
2498 history graph. This is sometimes known as 'backporting' or
2500 history graph. This is sometimes known as 'backporting' or
2499 'cherry-picking'. By default, graft will copy user, date, and
2501 'cherry-picking'. By default, graft will copy user, date, and
2500 description from the source changesets.
2502 description from the source changesets.
2501
2503
2502 Changesets that are ancestors of the current revision, that have
2504 Changesets that are ancestors of the current revision, that have
2503 already been grafted, or that are merges will be skipped.
2505 already been grafted, or that are merges will be skipped.
2504
2506
2505 If a graft merge results in conflicts, the graft process is
2507 If a graft merge results in conflicts, the graft process is
2506 aborted so that the current merge can be manually resolved. Once
2508 aborted so that the current merge can be manually resolved. Once
2507 all conflicts are addressed, the graft process can be continued
2509 all conflicts are addressed, the graft process can be continued
2508 with the -c/--continue option.
2510 with the -c/--continue option.
2509
2511
2510 .. note::
2512 .. note::
2511 The -c/--continue option does not reapply earlier options.
2513 The -c/--continue option does not reapply earlier options.
2512
2514
2513 .. container:: verbose
2515 .. container:: verbose
2514
2516
2515 Examples:
2517 Examples:
2516
2518
2517 - copy a single change to the stable branch and edit its description::
2519 - copy a single change to the stable branch and edit its description::
2518
2520
2519 hg update stable
2521 hg update stable
2520 hg graft --edit 9393
2522 hg graft --edit 9393
2521
2523
2522 - graft a range of changesets with one exception, updating dates::
2524 - graft a range of changesets with one exception, updating dates::
2523
2525
2524 hg graft -D "2085::2093 and not 2091"
2526 hg graft -D "2085::2093 and not 2091"
2525
2527
2526 - continue a graft after resolving conflicts::
2528 - continue a graft after resolving conflicts::
2527
2529
2528 hg graft -c
2530 hg graft -c
2529
2531
2530 - show the source of a grafted changeset::
2532 - show the source of a grafted changeset::
2531
2533
2532 hg log --debug -r tip
2534 hg log --debug -r tip
2533
2535
2534 Returns 0 on successful completion.
2536 Returns 0 on successful completion.
2535 '''
2537 '''
2536
2538
2537 if not opts.get('user') and opts.get('currentuser'):
2539 if not opts.get('user') and opts.get('currentuser'):
2538 opts['user'] = ui.username()
2540 opts['user'] = ui.username()
2539 if not opts.get('date') and opts.get('currentdate'):
2541 if not opts.get('date') and opts.get('currentdate'):
2540 opts['date'] = "%d %d" % util.makedate()
2542 opts['date'] = "%d %d" % util.makedate()
2541
2543
2542 editor = None
2544 editor = None
2543 if opts.get('edit'):
2545 if opts.get('edit'):
2544 editor = cmdutil.commitforceeditor
2546 editor = cmdutil.commitforceeditor
2545
2547
2546 cont = False
2548 cont = False
2547 if opts['continue']:
2549 if opts['continue']:
2548 cont = True
2550 cont = True
2549 if revs:
2551 if revs:
2550 raise util.Abort(_("can't specify --continue and revisions"))
2552 raise util.Abort(_("can't specify --continue and revisions"))
2551 # read in unfinished revisions
2553 # read in unfinished revisions
2552 try:
2554 try:
2553 nodes = repo.opener.read('graftstate').splitlines()
2555 nodes = repo.opener.read('graftstate').splitlines()
2554 revs = [repo[node].rev() for node in nodes]
2556 revs = [repo[node].rev() for node in nodes]
2555 except IOError, inst:
2557 except IOError, inst:
2556 if inst.errno != errno.ENOENT:
2558 if inst.errno != errno.ENOENT:
2557 raise
2559 raise
2558 raise util.Abort(_("no graft state found, can't continue"))
2560 raise util.Abort(_("no graft state found, can't continue"))
2559 else:
2561 else:
2560 cmdutil.bailifchanged(repo)
2562 cmdutil.bailifchanged(repo)
2561 if not revs:
2563 if not revs:
2562 raise util.Abort(_('no revisions specified'))
2564 raise util.Abort(_('no revisions specified'))
2563 revs = scmutil.revrange(repo, revs)
2565 revs = scmutil.revrange(repo, revs)
2564
2566
2565 # check for merges
2567 # check for merges
2566 for rev in repo.revs('%ld and merge()', revs):
2568 for rev in repo.revs('%ld and merge()', revs):
2567 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
2569 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
2568 revs.remove(rev)
2570 revs.remove(rev)
2569 if not revs:
2571 if not revs:
2570 return -1
2572 return -1
2571
2573
2572 # check for ancestors of dest branch
2574 # check for ancestors of dest branch
2573 for rev in repo.revs('::. and %ld', revs):
2575 for rev in repo.revs('::. and %ld', revs):
2574 ui.warn(_('skipping ancestor revision %s\n') % rev)
2576 ui.warn(_('skipping ancestor revision %s\n') % rev)
2575 revs.remove(rev)
2577 revs.remove(rev)
2576 if not revs:
2578 if not revs:
2577 return -1
2579 return -1
2578
2580
2579 # analyze revs for earlier grafts
2581 # analyze revs for earlier grafts
2580 ids = {}
2582 ids = {}
2581 for ctx in repo.set("%ld", revs):
2583 for ctx in repo.set("%ld", revs):
2582 ids[ctx.hex()] = ctx.rev()
2584 ids[ctx.hex()] = ctx.rev()
2583 n = ctx.extra().get('source')
2585 n = ctx.extra().get('source')
2584 if n:
2586 if n:
2585 ids[n] = ctx.rev()
2587 ids[n] = ctx.rev()
2586
2588
2587 # check ancestors for earlier grafts
2589 # check ancestors for earlier grafts
2588 ui.debug('scanning for duplicate grafts\n')
2590 ui.debug('scanning for duplicate grafts\n')
2589 for ctx in repo.set("::. - ::%ld", revs):
2591 for ctx in repo.set("::. - ::%ld", revs):
2590 n = ctx.extra().get('source')
2592 n = ctx.extra().get('source')
2591 if n in ids:
2593 if n in ids:
2592 r = repo[n].rev()
2594 r = repo[n].rev()
2593 if r in revs:
2595 if r in revs:
2594 ui.warn(_('skipping already grafted revision %s\n') % r)
2596 ui.warn(_('skipping already grafted revision %s\n') % r)
2595 revs.remove(r)
2597 revs.remove(r)
2596 elif ids[n] in revs:
2598 elif ids[n] in revs:
2597 ui.warn(_('skipping already grafted revision %s '
2599 ui.warn(_('skipping already grafted revision %s '
2598 '(same origin %d)\n') % (ids[n], r))
2600 '(same origin %d)\n') % (ids[n], r))
2599 revs.remove(ids[n])
2601 revs.remove(ids[n])
2600 elif ctx.hex() in ids:
2602 elif ctx.hex() in ids:
2601 r = ids[ctx.hex()]
2603 r = ids[ctx.hex()]
2602 ui.warn(_('skipping already grafted revision %s '
2604 ui.warn(_('skipping already grafted revision %s '
2603 '(was grafted from %d)\n') % (r, ctx.rev()))
2605 '(was grafted from %d)\n') % (r, ctx.rev()))
2604 revs.remove(r)
2606 revs.remove(r)
2605 if not revs:
2607 if not revs:
2606 return -1
2608 return -1
2607
2609
2608 for pos, ctx in enumerate(repo.set("%ld", revs)):
2610 for pos, ctx in enumerate(repo.set("%ld", revs)):
2609 current = repo['.']
2611 current = repo['.']
2610 ui.status(_('grafting revision %s\n') % ctx.rev())
2612 ui.status(_('grafting revision %s\n') % ctx.rev())
2611
2613
2612 # we don't merge the first commit when continuing
2614 # we don't merge the first commit when continuing
2613 if not cont:
2615 if not cont:
2614 # perform the graft merge with p1(rev) as 'ancestor'
2616 # perform the graft merge with p1(rev) as 'ancestor'
2615 try:
2617 try:
2616 # ui.forcemerge is an internal variable, do not document
2618 # ui.forcemerge is an internal variable, do not document
2617 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2619 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2618 stats = mergemod.update(repo, ctx.node(), True, True, False,
2620 stats = mergemod.update(repo, ctx.node(), True, True, False,
2619 ctx.p1().node())
2621 ctx.p1().node())
2620 finally:
2622 finally:
2621 ui.setconfig('ui', 'forcemerge', '')
2623 ui.setconfig('ui', 'forcemerge', '')
2622 # drop the second merge parent
2624 # drop the second merge parent
2623 repo.dirstate.setparents(current.node(), nullid)
2625 repo.dirstate.setparents(current.node(), nullid)
2624 repo.dirstate.write()
2626 repo.dirstate.write()
2625 # fix up dirstate for copies and renames
2627 # fix up dirstate for copies and renames
2626 cmdutil.duplicatecopies(repo, ctx.rev(), current.node(), nullid)
2628 cmdutil.duplicatecopies(repo, ctx.rev(), current.node(), nullid)
2627 # report any conflicts
2629 # report any conflicts
2628 if stats and stats[3] > 0:
2630 if stats and stats[3] > 0:
2629 # write out state for --continue
2631 # write out state for --continue
2630 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2632 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2631 repo.opener.write('graftstate', ''.join(nodelines))
2633 repo.opener.write('graftstate', ''.join(nodelines))
2632 raise util.Abort(
2634 raise util.Abort(
2633 _("unresolved conflicts, can't continue"),
2635 _("unresolved conflicts, can't continue"),
2634 hint=_('use hg resolve and hg graft --continue'))
2636 hint=_('use hg resolve and hg graft --continue'))
2635 else:
2637 else:
2636 cont = False
2638 cont = False
2637
2639
2638 # commit
2640 # commit
2639 source = ctx.extra().get('source')
2641 source = ctx.extra().get('source')
2640 if not source:
2642 if not source:
2641 source = ctx.hex()
2643 source = ctx.hex()
2642 extra = {'source': source}
2644 extra = {'source': source}
2643 user = ctx.user()
2645 user = ctx.user()
2644 if opts.get('user'):
2646 if opts.get('user'):
2645 user = opts['user']
2647 user = opts['user']
2646 date = ctx.date()
2648 date = ctx.date()
2647 if opts.get('date'):
2649 if opts.get('date'):
2648 date = opts['date']
2650 date = opts['date']
2649 repo.commit(text=ctx.description(), user=user,
2651 repo.commit(text=ctx.description(), user=user,
2650 date=date, extra=extra, editor=editor)
2652 date=date, extra=extra, editor=editor)
2651
2653
2652 # remove state when we complete successfully
2654 # remove state when we complete successfully
2653 if os.path.exists(repo.join('graftstate')):
2655 if os.path.exists(repo.join('graftstate')):
2654 util.unlinkpath(repo.join('graftstate'))
2656 util.unlinkpath(repo.join('graftstate'))
2655
2657
2656 return 0
2658 return 0
2657
2659
2658 @command('grep',
2660 @command('grep',
2659 [('0', 'print0', None, _('end fields with NUL')),
2661 [('0', 'print0', None, _('end fields with NUL')),
2660 ('', 'all', None, _('print all revisions that match')),
2662 ('', 'all', None, _('print all revisions that match')),
2661 ('a', 'text', None, _('treat all files as text')),
2663 ('a', 'text', None, _('treat all files as text')),
2662 ('f', 'follow', None,
2664 ('f', 'follow', None,
2663 _('follow changeset history,'
2665 _('follow changeset history,'
2664 ' or file history across copies and renames')),
2666 ' or file history across copies and renames')),
2665 ('i', 'ignore-case', None, _('ignore case when matching')),
2667 ('i', 'ignore-case', None, _('ignore case when matching')),
2666 ('l', 'files-with-matches', None,
2668 ('l', 'files-with-matches', None,
2667 _('print only filenames and revisions that match')),
2669 _('print only filenames and revisions that match')),
2668 ('n', 'line-number', None, _('print matching line numbers')),
2670 ('n', 'line-number', None, _('print matching line numbers')),
2669 ('r', 'rev', [],
2671 ('r', 'rev', [],
2670 _('only search files changed within revision range'), _('REV')),
2672 _('only search files changed within revision range'), _('REV')),
2671 ('u', 'user', None, _('list the author (long with -v)')),
2673 ('u', 'user', None, _('list the author (long with -v)')),
2672 ('d', 'date', None, _('list the date (short with -q)')),
2674 ('d', 'date', None, _('list the date (short with -q)')),
2673 ] + walkopts,
2675 ] + walkopts,
2674 _('[OPTION]... PATTERN [FILE]...'))
2676 _('[OPTION]... PATTERN [FILE]...'))
2675 def grep(ui, repo, pattern, *pats, **opts):
2677 def grep(ui, repo, pattern, *pats, **opts):
2676 """search for a pattern in specified files and revisions
2678 """search for a pattern in specified files and revisions
2677
2679
2678 Search revisions of files for a regular expression.
2680 Search revisions of files for a regular expression.
2679
2681
2680 This command behaves differently than Unix grep. It only accepts
2682 This command behaves differently than Unix grep. It only accepts
2681 Python/Perl regexps. It searches repository history, not the
2683 Python/Perl regexps. It searches repository history, not the
2682 working directory. It always prints the revision number in which a
2684 working directory. It always prints the revision number in which a
2683 match appears.
2685 match appears.
2684
2686
2685 By default, grep only prints output for the first revision of a
2687 By default, grep only prints output for the first revision of a
2686 file in which it finds a match. To get it to print every revision
2688 file in which it finds a match. To get it to print every revision
2687 that contains a change in match status ("-" for a match that
2689 that contains a change in match status ("-" for a match that
2688 becomes a non-match, or "+" for a non-match that becomes a match),
2690 becomes a non-match, or "+" for a non-match that becomes a match),
2689 use the --all flag.
2691 use the --all flag.
2690
2692
2691 Returns 0 if a match is found, 1 otherwise.
2693 Returns 0 if a match is found, 1 otherwise.
2692 """
2694 """
2693 reflags = 0
2695 reflags = 0
2694 if opts.get('ignore_case'):
2696 if opts.get('ignore_case'):
2695 reflags |= re.I
2697 reflags |= re.I
2696 try:
2698 try:
2697 regexp = re.compile(pattern, reflags)
2699 regexp = re.compile(pattern, reflags)
2698 except re.error, inst:
2700 except re.error, inst:
2699 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2701 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2700 return 1
2702 return 1
2701 sep, eol = ':', '\n'
2703 sep, eol = ':', '\n'
2702 if opts.get('print0'):
2704 if opts.get('print0'):
2703 sep = eol = '\0'
2705 sep = eol = '\0'
2704
2706
2705 getfile = util.lrucachefunc(repo.file)
2707 getfile = util.lrucachefunc(repo.file)
2706
2708
2707 def matchlines(body):
2709 def matchlines(body):
2708 begin = 0
2710 begin = 0
2709 linenum = 0
2711 linenum = 0
2710 while True:
2712 while True:
2711 match = regexp.search(body, begin)
2713 match = regexp.search(body, begin)
2712 if not match:
2714 if not match:
2713 break
2715 break
2714 mstart, mend = match.span()
2716 mstart, mend = match.span()
2715 linenum += body.count('\n', begin, mstart) + 1
2717 linenum += body.count('\n', begin, mstart) + 1
2716 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2718 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2717 begin = body.find('\n', mend) + 1 or len(body) + 1
2719 begin = body.find('\n', mend) + 1 or len(body) + 1
2718 lend = begin - 1
2720 lend = begin - 1
2719 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2721 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2720
2722
2721 class linestate(object):
2723 class linestate(object):
2722 def __init__(self, line, linenum, colstart, colend):
2724 def __init__(self, line, linenum, colstart, colend):
2723 self.line = line
2725 self.line = line
2724 self.linenum = linenum
2726 self.linenum = linenum
2725 self.colstart = colstart
2727 self.colstart = colstart
2726 self.colend = colend
2728 self.colend = colend
2727
2729
2728 def __hash__(self):
2730 def __hash__(self):
2729 return hash((self.linenum, self.line))
2731 return hash((self.linenum, self.line))
2730
2732
2731 def __eq__(self, other):
2733 def __eq__(self, other):
2732 return self.line == other.line
2734 return self.line == other.line
2733
2735
2734 matches = {}
2736 matches = {}
2735 copies = {}
2737 copies = {}
2736 def grepbody(fn, rev, body):
2738 def grepbody(fn, rev, body):
2737 matches[rev].setdefault(fn, [])
2739 matches[rev].setdefault(fn, [])
2738 m = matches[rev][fn]
2740 m = matches[rev][fn]
2739 for lnum, cstart, cend, line in matchlines(body):
2741 for lnum, cstart, cend, line in matchlines(body):
2740 s = linestate(line, lnum, cstart, cend)
2742 s = linestate(line, lnum, cstart, cend)
2741 m.append(s)
2743 m.append(s)
2742
2744
2743 def difflinestates(a, b):
2745 def difflinestates(a, b):
2744 sm = difflib.SequenceMatcher(None, a, b)
2746 sm = difflib.SequenceMatcher(None, a, b)
2745 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2747 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2746 if tag == 'insert':
2748 if tag == 'insert':
2747 for i in xrange(blo, bhi):
2749 for i in xrange(blo, bhi):
2748 yield ('+', b[i])
2750 yield ('+', b[i])
2749 elif tag == 'delete':
2751 elif tag == 'delete':
2750 for i in xrange(alo, ahi):
2752 for i in xrange(alo, ahi):
2751 yield ('-', a[i])
2753 yield ('-', a[i])
2752 elif tag == 'replace':
2754 elif tag == 'replace':
2753 for i in xrange(alo, ahi):
2755 for i in xrange(alo, ahi):
2754 yield ('-', a[i])
2756 yield ('-', a[i])
2755 for i in xrange(blo, bhi):
2757 for i in xrange(blo, bhi):
2756 yield ('+', b[i])
2758 yield ('+', b[i])
2757
2759
2758 def display(fn, ctx, pstates, states):
2760 def display(fn, ctx, pstates, states):
2759 rev = ctx.rev()
2761 rev = ctx.rev()
2760 datefunc = ui.quiet and util.shortdate or util.datestr
2762 datefunc = ui.quiet and util.shortdate or util.datestr
2761 found = False
2763 found = False
2762 filerevmatches = {}
2764 filerevmatches = {}
2763 def binary():
2765 def binary():
2764 flog = getfile(fn)
2766 flog = getfile(fn)
2765 return util.binary(flog.read(ctx.filenode(fn)))
2767 return util.binary(flog.read(ctx.filenode(fn)))
2766
2768
2767 if opts.get('all'):
2769 if opts.get('all'):
2768 iter = difflinestates(pstates, states)
2770 iter = difflinestates(pstates, states)
2769 else:
2771 else:
2770 iter = [('', l) for l in states]
2772 iter = [('', l) for l in states]
2771 for change, l in iter:
2773 for change, l in iter:
2772 cols = [fn, str(rev)]
2774 cols = [fn, str(rev)]
2773 before, match, after = None, None, None
2775 before, match, after = None, None, None
2774 if opts.get('line_number'):
2776 if opts.get('line_number'):
2775 cols.append(str(l.linenum))
2777 cols.append(str(l.linenum))
2776 if opts.get('all'):
2778 if opts.get('all'):
2777 cols.append(change)
2779 cols.append(change)
2778 if opts.get('user'):
2780 if opts.get('user'):
2779 cols.append(ui.shortuser(ctx.user()))
2781 cols.append(ui.shortuser(ctx.user()))
2780 if opts.get('date'):
2782 if opts.get('date'):
2781 cols.append(datefunc(ctx.date()))
2783 cols.append(datefunc(ctx.date()))
2782 if opts.get('files_with_matches'):
2784 if opts.get('files_with_matches'):
2783 c = (fn, rev)
2785 c = (fn, rev)
2784 if c in filerevmatches:
2786 if c in filerevmatches:
2785 continue
2787 continue
2786 filerevmatches[c] = 1
2788 filerevmatches[c] = 1
2787 else:
2789 else:
2788 before = l.line[:l.colstart]
2790 before = l.line[:l.colstart]
2789 match = l.line[l.colstart:l.colend]
2791 match = l.line[l.colstart:l.colend]
2790 after = l.line[l.colend:]
2792 after = l.line[l.colend:]
2791 ui.write(sep.join(cols))
2793 ui.write(sep.join(cols))
2792 if before is not None:
2794 if before is not None:
2793 if not opts.get('text') and binary():
2795 if not opts.get('text') and binary():
2794 ui.write(sep + " Binary file matches")
2796 ui.write(sep + " Binary file matches")
2795 else:
2797 else:
2796 ui.write(sep + before)
2798 ui.write(sep + before)
2797 ui.write(match, label='grep.match')
2799 ui.write(match, label='grep.match')
2798 ui.write(after)
2800 ui.write(after)
2799 ui.write(eol)
2801 ui.write(eol)
2800 found = True
2802 found = True
2801 return found
2803 return found
2802
2804
2803 skip = {}
2805 skip = {}
2804 revfiles = {}
2806 revfiles = {}
2805 matchfn = scmutil.match(repo[None], pats, opts)
2807 matchfn = scmutil.match(repo[None], pats, opts)
2806 found = False
2808 found = False
2807 follow = opts.get('follow')
2809 follow = opts.get('follow')
2808
2810
2809 def prep(ctx, fns):
2811 def prep(ctx, fns):
2810 rev = ctx.rev()
2812 rev = ctx.rev()
2811 pctx = ctx.p1()
2813 pctx = ctx.p1()
2812 parent = pctx.rev()
2814 parent = pctx.rev()
2813 matches.setdefault(rev, {})
2815 matches.setdefault(rev, {})
2814 matches.setdefault(parent, {})
2816 matches.setdefault(parent, {})
2815 files = revfiles.setdefault(rev, [])
2817 files = revfiles.setdefault(rev, [])
2816 for fn in fns:
2818 for fn in fns:
2817 flog = getfile(fn)
2819 flog = getfile(fn)
2818 try:
2820 try:
2819 fnode = ctx.filenode(fn)
2821 fnode = ctx.filenode(fn)
2820 except error.LookupError:
2822 except error.LookupError:
2821 continue
2823 continue
2822
2824
2823 copied = flog.renamed(fnode)
2825 copied = flog.renamed(fnode)
2824 copy = follow and copied and copied[0]
2826 copy = follow and copied and copied[0]
2825 if copy:
2827 if copy:
2826 copies.setdefault(rev, {})[fn] = copy
2828 copies.setdefault(rev, {})[fn] = copy
2827 if fn in skip:
2829 if fn in skip:
2828 if copy:
2830 if copy:
2829 skip[copy] = True
2831 skip[copy] = True
2830 continue
2832 continue
2831 files.append(fn)
2833 files.append(fn)
2832
2834
2833 if fn not in matches[rev]:
2835 if fn not in matches[rev]:
2834 grepbody(fn, rev, flog.read(fnode))
2836 grepbody(fn, rev, flog.read(fnode))
2835
2837
2836 pfn = copy or fn
2838 pfn = copy or fn
2837 if pfn not in matches[parent]:
2839 if pfn not in matches[parent]:
2838 try:
2840 try:
2839 fnode = pctx.filenode(pfn)
2841 fnode = pctx.filenode(pfn)
2840 grepbody(pfn, parent, flog.read(fnode))
2842 grepbody(pfn, parent, flog.read(fnode))
2841 except error.LookupError:
2843 except error.LookupError:
2842 pass
2844 pass
2843
2845
2844 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2846 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2845 rev = ctx.rev()
2847 rev = ctx.rev()
2846 parent = ctx.p1().rev()
2848 parent = ctx.p1().rev()
2847 for fn in sorted(revfiles.get(rev, [])):
2849 for fn in sorted(revfiles.get(rev, [])):
2848 states = matches[rev][fn]
2850 states = matches[rev][fn]
2849 copy = copies.get(rev, {}).get(fn)
2851 copy = copies.get(rev, {}).get(fn)
2850 if fn in skip:
2852 if fn in skip:
2851 if copy:
2853 if copy:
2852 skip[copy] = True
2854 skip[copy] = True
2853 continue
2855 continue
2854 pstates = matches.get(parent, {}).get(copy or fn, [])
2856 pstates = matches.get(parent, {}).get(copy or fn, [])
2855 if pstates or states:
2857 if pstates or states:
2856 r = display(fn, ctx, pstates, states)
2858 r = display(fn, ctx, pstates, states)
2857 found = found or r
2859 found = found or r
2858 if r and not opts.get('all'):
2860 if r and not opts.get('all'):
2859 skip[fn] = True
2861 skip[fn] = True
2860 if copy:
2862 if copy:
2861 skip[copy] = True
2863 skip[copy] = True
2862 del matches[rev]
2864 del matches[rev]
2863 del revfiles[rev]
2865 del revfiles[rev]
2864
2866
2865 return not found
2867 return not found
2866
2868
2867 @command('heads',
2869 @command('heads',
2868 [('r', 'rev', '',
2870 [('r', 'rev', '',
2869 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2871 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2870 ('t', 'topo', False, _('show topological heads only')),
2872 ('t', 'topo', False, _('show topological heads only')),
2871 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2873 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2872 ('c', 'closed', False, _('show normal and closed branch heads')),
2874 ('c', 'closed', False, _('show normal and closed branch heads')),
2873 ] + templateopts,
2875 ] + templateopts,
2874 _('[-ac] [-r STARTREV] [REV]...'))
2876 _('[-ac] [-r STARTREV] [REV]...'))
2875 def heads(ui, repo, *branchrevs, **opts):
2877 def heads(ui, repo, *branchrevs, **opts):
2876 """show current repository heads or show branch heads
2878 """show current repository heads or show branch heads
2877
2879
2878 With no arguments, show all repository branch heads.
2880 With no arguments, show all repository branch heads.
2879
2881
2880 Repository "heads" are changesets with no child changesets. They are
2882 Repository "heads" are changesets with no child changesets. They are
2881 where development generally takes place and are the usual targets
2883 where development generally takes place and are the usual targets
2882 for update and merge operations. Branch heads are changesets that have
2884 for update and merge operations. Branch heads are changesets that have
2883 no child changeset on the same branch.
2885 no child changeset on the same branch.
2884
2886
2885 If one or more REVs are given, only branch heads on the branches
2887 If one or more REVs are given, only branch heads on the branches
2886 associated with the specified changesets are shown. This means
2888 associated with the specified changesets are shown. This means
2887 that you can use :hg:`heads foo` to see the heads on a branch
2889 that you can use :hg:`heads foo` to see the heads on a branch
2888 named ``foo``.
2890 named ``foo``.
2889
2891
2890 If -c/--closed is specified, also show branch heads marked closed
2892 If -c/--closed is specified, also show branch heads marked closed
2891 (see :hg:`commit --close-branch`).
2893 (see :hg:`commit --close-branch`).
2892
2894
2893 If STARTREV is specified, only those heads that are descendants of
2895 If STARTREV is specified, only those heads that are descendants of
2894 STARTREV will be displayed.
2896 STARTREV will be displayed.
2895
2897
2896 If -t/--topo is specified, named branch mechanics will be ignored and only
2898 If -t/--topo is specified, named branch mechanics will be ignored and only
2897 changesets without children will be shown.
2899 changesets without children will be shown.
2898
2900
2899 Returns 0 if matching heads are found, 1 if not.
2901 Returns 0 if matching heads are found, 1 if not.
2900 """
2902 """
2901
2903
2902 start = None
2904 start = None
2903 if 'rev' in opts:
2905 if 'rev' in opts:
2904 start = scmutil.revsingle(repo, opts['rev'], None).node()
2906 start = scmutil.revsingle(repo, opts['rev'], None).node()
2905
2907
2906 if opts.get('topo'):
2908 if opts.get('topo'):
2907 heads = [repo[h] for h in repo.heads(start)]
2909 heads = [repo[h] for h in repo.heads(start)]
2908 else:
2910 else:
2909 heads = []
2911 heads = []
2910 for branch in repo.branchmap():
2912 for branch in repo.branchmap():
2911 heads += repo.branchheads(branch, start, opts.get('closed'))
2913 heads += repo.branchheads(branch, start, opts.get('closed'))
2912 heads = [repo[h] for h in heads]
2914 heads = [repo[h] for h in heads]
2913
2915
2914 if branchrevs:
2916 if branchrevs:
2915 branches = set(repo[br].branch() for br in branchrevs)
2917 branches = set(repo[br].branch() for br in branchrevs)
2916 heads = [h for h in heads if h.branch() in branches]
2918 heads = [h for h in heads if h.branch() in branches]
2917
2919
2918 if opts.get('active') and branchrevs:
2920 if opts.get('active') and branchrevs:
2919 dagheads = repo.heads(start)
2921 dagheads = repo.heads(start)
2920 heads = [h for h in heads if h.node() in dagheads]
2922 heads = [h for h in heads if h.node() in dagheads]
2921
2923
2922 if branchrevs:
2924 if branchrevs:
2923 haveheads = set(h.branch() for h in heads)
2925 haveheads = set(h.branch() for h in heads)
2924 if branches - haveheads:
2926 if branches - haveheads:
2925 headless = ', '.join(b for b in branches - haveheads)
2927 headless = ', '.join(b for b in branches - haveheads)
2926 msg = _('no open branch heads found on branches %s')
2928 msg = _('no open branch heads found on branches %s')
2927 if opts.get('rev'):
2929 if opts.get('rev'):
2928 msg += _(' (started at %s)' % opts['rev'])
2930 msg += _(' (started at %s)' % opts['rev'])
2929 ui.warn((msg + '\n') % headless)
2931 ui.warn((msg + '\n') % headless)
2930
2932
2931 if not heads:
2933 if not heads:
2932 return 1
2934 return 1
2933
2935
2934 heads = sorted(heads, key=lambda x: -x.rev())
2936 heads = sorted(heads, key=lambda x: -x.rev())
2935 displayer = cmdutil.show_changeset(ui, repo, opts)
2937 displayer = cmdutil.show_changeset(ui, repo, opts)
2936 for ctx in heads:
2938 for ctx in heads:
2937 displayer.show(ctx)
2939 displayer.show(ctx)
2938 displayer.close()
2940 displayer.close()
2939
2941
2940 @command('help',
2942 @command('help',
2941 [('e', 'extension', None, _('show only help for extensions')),
2943 [('e', 'extension', None, _('show only help for extensions')),
2942 ('c', 'command', None, _('show only help for commands'))],
2944 ('c', 'command', None, _('show only help for commands'))],
2943 _('[-ec] [TOPIC]'))
2945 _('[-ec] [TOPIC]'))
2944 def help_(ui, name=None, unknowncmd=False, full=True, **opts):
2946 def help_(ui, name=None, unknowncmd=False, full=True, **opts):
2945 """show help for a given topic or a help overview
2947 """show help for a given topic or a help overview
2946
2948
2947 With no arguments, print a list of commands with short help messages.
2949 With no arguments, print a list of commands with short help messages.
2948
2950
2949 Given a topic, extension, or command name, print help for that
2951 Given a topic, extension, or command name, print help for that
2950 topic.
2952 topic.
2951
2953
2952 Returns 0 if successful.
2954 Returns 0 if successful.
2953 """
2955 """
2954
2956
2955 textwidth = min(ui.termwidth(), 80) - 2
2957 textwidth = min(ui.termwidth(), 80) - 2
2956
2958
2957 def optrst(options):
2959 def optrst(options):
2958 data = []
2960 data = []
2959 multioccur = False
2961 multioccur = False
2960 for option in options:
2962 for option in options:
2961 if len(option) == 5:
2963 if len(option) == 5:
2962 shortopt, longopt, default, desc, optlabel = option
2964 shortopt, longopt, default, desc, optlabel = option
2963 else:
2965 else:
2964 shortopt, longopt, default, desc = option
2966 shortopt, longopt, default, desc = option
2965 optlabel = _("VALUE") # default label
2967 optlabel = _("VALUE") # default label
2966
2968
2967 if _("DEPRECATED") in desc and not ui.verbose:
2969 if _("DEPRECATED") in desc and not ui.verbose:
2968 continue
2970 continue
2969
2971
2970 so = ''
2972 so = ''
2971 if shortopt:
2973 if shortopt:
2972 so = '-' + shortopt
2974 so = '-' + shortopt
2973 lo = '--' + longopt
2975 lo = '--' + longopt
2974 if default:
2976 if default:
2975 desc += _(" (default: %s)") % default
2977 desc += _(" (default: %s)") % default
2976
2978
2977 if isinstance(default, list):
2979 if isinstance(default, list):
2978 lo += " %s [+]" % optlabel
2980 lo += " %s [+]" % optlabel
2979 multioccur = True
2981 multioccur = True
2980 elif (default is not None) and not isinstance(default, bool):
2982 elif (default is not None) and not isinstance(default, bool):
2981 lo += " %s" % optlabel
2983 lo += " %s" % optlabel
2982
2984
2983 data.append((so, lo, desc))
2985 data.append((so, lo, desc))
2984
2986
2985 rst = minirst.maketable(data, 1)
2987 rst = minirst.maketable(data, 1)
2986
2988
2987 if multioccur:
2989 if multioccur:
2988 rst += _("\n[+] marked option can be specified multiple times\n")
2990 rst += _("\n[+] marked option can be specified multiple times\n")
2989
2991
2990 return rst
2992 return rst
2991
2993
2992 # list all option lists
2994 # list all option lists
2993 def opttext(optlist, width):
2995 def opttext(optlist, width):
2994 rst = ''
2996 rst = ''
2995 if not optlist:
2997 if not optlist:
2996 return ''
2998 return ''
2997
2999
2998 for title, options in optlist:
3000 for title, options in optlist:
2999 rst += '\n%s\n' % title
3001 rst += '\n%s\n' % title
3000 if options:
3002 if options:
3001 rst += "\n"
3003 rst += "\n"
3002 rst += optrst(options)
3004 rst += optrst(options)
3003 rst += '\n'
3005 rst += '\n'
3004
3006
3005 return '\n' + minirst.format(rst, width)
3007 return '\n' + minirst.format(rst, width)
3006
3008
3007 def addglobalopts(optlist, aliases):
3009 def addglobalopts(optlist, aliases):
3008 if ui.quiet:
3010 if ui.quiet:
3009 return []
3011 return []
3010
3012
3011 if ui.verbose:
3013 if ui.verbose:
3012 optlist.append((_("global options:"), globalopts))
3014 optlist.append((_("global options:"), globalopts))
3013 if name == 'shortlist':
3015 if name == 'shortlist':
3014 optlist.append((_('use "hg help" for the full list '
3016 optlist.append((_('use "hg help" for the full list '
3015 'of commands'), ()))
3017 'of commands'), ()))
3016 else:
3018 else:
3017 if name == 'shortlist':
3019 if name == 'shortlist':
3018 msg = _('use "hg help" for the full list of commands '
3020 msg = _('use "hg help" for the full list of commands '
3019 'or "hg -v" for details')
3021 'or "hg -v" for details')
3020 elif name and not full:
3022 elif name and not full:
3021 msg = _('use "hg help %s" to show the full help text' % name)
3023 msg = _('use "hg help %s" to show the full help text' % name)
3022 elif aliases:
3024 elif aliases:
3023 msg = _('use "hg -v help%s" to show builtin aliases and '
3025 msg = _('use "hg -v help%s" to show builtin aliases and '
3024 'global options') % (name and " " + name or "")
3026 'global options') % (name and " " + name or "")
3025 else:
3027 else:
3026 msg = _('use "hg -v help %s" to show more info') % name
3028 msg = _('use "hg -v help %s" to show more info') % name
3027 optlist.append((msg, ()))
3029 optlist.append((msg, ()))
3028
3030
3029 def helpcmd(name):
3031 def helpcmd(name):
3030 try:
3032 try:
3031 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
3033 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
3032 except error.AmbiguousCommand, inst:
3034 except error.AmbiguousCommand, inst:
3033 # py3k fix: except vars can't be used outside the scope of the
3035 # py3k fix: except vars can't be used outside the scope of the
3034 # except block, nor can be used inside a lambda. python issue4617
3036 # except block, nor can be used inside a lambda. python issue4617
3035 prefix = inst.args[0]
3037 prefix = inst.args[0]
3036 select = lambda c: c.lstrip('^').startswith(prefix)
3038 select = lambda c: c.lstrip('^').startswith(prefix)
3037 helplist(select)
3039 helplist(select)
3038 return
3040 return
3039
3041
3040 # check if it's an invalid alias and display its error if it is
3042 # check if it's an invalid alias and display its error if it is
3041 if getattr(entry[0], 'badalias', False):
3043 if getattr(entry[0], 'badalias', False):
3042 if not unknowncmd:
3044 if not unknowncmd:
3043 entry[0](ui)
3045 entry[0](ui)
3044 return
3046 return
3045
3047
3046 rst = ""
3048 rst = ""
3047
3049
3048 # synopsis
3050 # synopsis
3049 if len(entry) > 2:
3051 if len(entry) > 2:
3050 if entry[2].startswith('hg'):
3052 if entry[2].startswith('hg'):
3051 rst += "%s\n" % entry[2]
3053 rst += "%s\n" % entry[2]
3052 else:
3054 else:
3053 rst += 'hg %s %s\n' % (aliases[0], entry[2])
3055 rst += 'hg %s %s\n' % (aliases[0], entry[2])
3054 else:
3056 else:
3055 rst += 'hg %s\n' % aliases[0]
3057 rst += 'hg %s\n' % aliases[0]
3056
3058
3057 # aliases
3059 # aliases
3058 if full and not ui.quiet and len(aliases) > 1:
3060 if full and not ui.quiet and len(aliases) > 1:
3059 rst += _("\naliases: %s\n") % ', '.join(aliases[1:])
3061 rst += _("\naliases: %s\n") % ', '.join(aliases[1:])
3060
3062
3061 # description
3063 # description
3062 doc = gettext(entry[0].__doc__)
3064 doc = gettext(entry[0].__doc__)
3063 if not doc:
3065 if not doc:
3064 doc = _("(no help text available)")
3066 doc = _("(no help text available)")
3065 if util.safehasattr(entry[0], 'definition'): # aliased command
3067 if util.safehasattr(entry[0], 'definition'): # aliased command
3066 if entry[0].definition.startswith('!'): # shell alias
3068 if entry[0].definition.startswith('!'): # shell alias
3067 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
3069 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
3068 else:
3070 else:
3069 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
3071 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
3070 if ui.quiet or not full:
3072 if ui.quiet or not full:
3071 doc = doc.splitlines()[0]
3073 doc = doc.splitlines()[0]
3072 rst += "\n" + doc + "\n"
3074 rst += "\n" + doc + "\n"
3073
3075
3074 # check if this command shadows a non-trivial (multi-line)
3076 # check if this command shadows a non-trivial (multi-line)
3075 # extension help text
3077 # extension help text
3076 try:
3078 try:
3077 mod = extensions.find(name)
3079 mod = extensions.find(name)
3078 doc = gettext(mod.__doc__) or ''
3080 doc = gettext(mod.__doc__) or ''
3079 if '\n' in doc.strip():
3081 if '\n' in doc.strip():
3080 msg = _('use "hg help -e %s" to show help for '
3082 msg = _('use "hg help -e %s" to show help for '
3081 'the %s extension') % (name, name)
3083 'the %s extension') % (name, name)
3082 rst += '\n%s\n' % msg
3084 rst += '\n%s\n' % msg
3083 except KeyError:
3085 except KeyError:
3084 pass
3086 pass
3085
3087
3086 # options
3088 # options
3087 if not ui.quiet and entry[1]:
3089 if not ui.quiet and entry[1]:
3088 rst += '\noptions:\n\n'
3090 rst += '\noptions:\n\n'
3089 rst += optrst(entry[1])
3091 rst += optrst(entry[1])
3090
3092
3091 if ui.verbose:
3093 if ui.verbose:
3092 rst += '\nglobal options:\n\n'
3094 rst += '\nglobal options:\n\n'
3093 rst += optrst(globalopts)
3095 rst += optrst(globalopts)
3094
3096
3095 keep = ui.verbose and ['verbose'] or []
3097 keep = ui.verbose and ['verbose'] or []
3096 formatted, pruned = minirst.format(rst, textwidth, keep=keep)
3098 formatted, pruned = minirst.format(rst, textwidth, keep=keep)
3097 ui.write(formatted)
3099 ui.write(formatted)
3098
3100
3099 if not ui.verbose:
3101 if not ui.verbose:
3100 if not full:
3102 if not full:
3101 ui.write(_('\nuse "hg help %s" to show the full help text\n')
3103 ui.write(_('\nuse "hg help %s" to show the full help text\n')
3102 % name)
3104 % name)
3103 elif not ui.quiet:
3105 elif not ui.quiet:
3104 ui.write(_('\nuse "hg -v help %s" to show more info\n') % name)
3106 ui.write(_('\nuse "hg -v help %s" to show more info\n') % name)
3105
3107
3106
3108
3107 def helplist(select=None):
3109 def helplist(select=None):
3108 # list of commands
3110 # list of commands
3109 if name == "shortlist":
3111 if name == "shortlist":
3110 header = _('basic commands:\n\n')
3112 header = _('basic commands:\n\n')
3111 else:
3113 else:
3112 header = _('list of commands:\n\n')
3114 header = _('list of commands:\n\n')
3113
3115
3114 h = {}
3116 h = {}
3115 cmds = {}
3117 cmds = {}
3116 for c, e in table.iteritems():
3118 for c, e in table.iteritems():
3117 f = c.split("|", 1)[0]
3119 f = c.split("|", 1)[0]
3118 if select and not select(f):
3120 if select and not select(f):
3119 continue
3121 continue
3120 if (not select and name != 'shortlist' and
3122 if (not select and name != 'shortlist' and
3121 e[0].__module__ != __name__):
3123 e[0].__module__ != __name__):
3122 continue
3124 continue
3123 if name == "shortlist" and not f.startswith("^"):
3125 if name == "shortlist" and not f.startswith("^"):
3124 continue
3126 continue
3125 f = f.lstrip("^")
3127 f = f.lstrip("^")
3126 if not ui.debugflag and f.startswith("debug"):
3128 if not ui.debugflag and f.startswith("debug"):
3127 continue
3129 continue
3128 doc = e[0].__doc__
3130 doc = e[0].__doc__
3129 if doc and 'DEPRECATED' in doc and not ui.verbose:
3131 if doc and 'DEPRECATED' in doc and not ui.verbose:
3130 continue
3132 continue
3131 doc = gettext(doc)
3133 doc = gettext(doc)
3132 if not doc:
3134 if not doc:
3133 doc = _("(no help text available)")
3135 doc = _("(no help text available)")
3134 h[f] = doc.splitlines()[0].rstrip()
3136 h[f] = doc.splitlines()[0].rstrip()
3135 cmds[f] = c.lstrip("^")
3137 cmds[f] = c.lstrip("^")
3136
3138
3137 if not h:
3139 if not h:
3138 ui.status(_('no commands defined\n'))
3140 ui.status(_('no commands defined\n'))
3139 return
3141 return
3140
3142
3141 ui.status(header)
3143 ui.status(header)
3142 fns = sorted(h)
3144 fns = sorted(h)
3143 m = max(map(len, fns))
3145 m = max(map(len, fns))
3144 for f in fns:
3146 for f in fns:
3145 if ui.verbose:
3147 if ui.verbose:
3146 commands = cmds[f].replace("|",", ")
3148 commands = cmds[f].replace("|",", ")
3147 ui.write(" %s:\n %s\n"%(commands, h[f]))
3149 ui.write(" %s:\n %s\n"%(commands, h[f]))
3148 else:
3150 else:
3149 ui.write('%s\n' % (util.wrap(h[f], textwidth,
3151 ui.write('%s\n' % (util.wrap(h[f], textwidth,
3150 initindent=' %-*s ' % (m, f),
3152 initindent=' %-*s ' % (m, f),
3151 hangindent=' ' * (m + 4))))
3153 hangindent=' ' * (m + 4))))
3152
3154
3153 if not name:
3155 if not name:
3154 text = help.listexts(_('enabled extensions:'), extensions.enabled())
3156 text = help.listexts(_('enabled extensions:'), extensions.enabled())
3155 if text:
3157 if text:
3156 ui.write("\n%s" % minirst.format(text, textwidth))
3158 ui.write("\n%s" % minirst.format(text, textwidth))
3157
3159
3158 ui.write(_("\nadditional help topics:\n\n"))
3160 ui.write(_("\nadditional help topics:\n\n"))
3159 topics = []
3161 topics = []
3160 for names, header, doc in help.helptable:
3162 for names, header, doc in help.helptable:
3161 topics.append((sorted(names, key=len, reverse=True)[0], header))
3163 topics.append((sorted(names, key=len, reverse=True)[0], header))
3162 topics_len = max([len(s[0]) for s in topics])
3164 topics_len = max([len(s[0]) for s in topics])
3163 for t, desc in topics:
3165 for t, desc in topics:
3164 ui.write(" %-*s %s\n" % (topics_len, t, desc))
3166 ui.write(" %-*s %s\n" % (topics_len, t, desc))
3165
3167
3166 optlist = []
3168 optlist = []
3167 addglobalopts(optlist, True)
3169 addglobalopts(optlist, True)
3168 ui.write(opttext(optlist, textwidth))
3170 ui.write(opttext(optlist, textwidth))
3169
3171
3170 def helptopic(name):
3172 def helptopic(name):
3171 for names, header, doc in help.helptable:
3173 for names, header, doc in help.helptable:
3172 if name in names:
3174 if name in names:
3173 break
3175 break
3174 else:
3176 else:
3175 raise error.UnknownCommand(name)
3177 raise error.UnknownCommand(name)
3176
3178
3177 # description
3179 # description
3178 if not doc:
3180 if not doc:
3179 doc = _("(no help text available)")
3181 doc = _("(no help text available)")
3180 if util.safehasattr(doc, '__call__'):
3182 if util.safehasattr(doc, '__call__'):
3181 doc = doc()
3183 doc = doc()
3182
3184
3183 ui.write("%s\n\n" % header)
3185 ui.write("%s\n\n" % header)
3184 ui.write("%s" % minirst.format(doc, textwidth, indent=4))
3186 ui.write("%s" % minirst.format(doc, textwidth, indent=4))
3185 try:
3187 try:
3186 cmdutil.findcmd(name, table)
3188 cmdutil.findcmd(name, table)
3187 ui.write(_('\nuse "hg help -c %s" to see help for '
3189 ui.write(_('\nuse "hg help -c %s" to see help for '
3188 'the %s command\n') % (name, name))
3190 'the %s command\n') % (name, name))
3189 except error.UnknownCommand:
3191 except error.UnknownCommand:
3190 pass
3192 pass
3191
3193
3192 def helpext(name):
3194 def helpext(name):
3193 try:
3195 try:
3194 mod = extensions.find(name)
3196 mod = extensions.find(name)
3195 doc = gettext(mod.__doc__) or _('no help text available')
3197 doc = gettext(mod.__doc__) or _('no help text available')
3196 except KeyError:
3198 except KeyError:
3197 mod = None
3199 mod = None
3198 doc = extensions.disabledext(name)
3200 doc = extensions.disabledext(name)
3199 if not doc:
3201 if not doc:
3200 raise error.UnknownCommand(name)
3202 raise error.UnknownCommand(name)
3201
3203
3202 if '\n' not in doc:
3204 if '\n' not in doc:
3203 head, tail = doc, ""
3205 head, tail = doc, ""
3204 else:
3206 else:
3205 head, tail = doc.split('\n', 1)
3207 head, tail = doc.split('\n', 1)
3206 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
3208 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
3207 if tail:
3209 if tail:
3208 ui.write(minirst.format(tail, textwidth))
3210 ui.write(minirst.format(tail, textwidth))
3209 ui.status('\n')
3211 ui.status('\n')
3210
3212
3211 if mod:
3213 if mod:
3212 try:
3214 try:
3213 ct = mod.cmdtable
3215 ct = mod.cmdtable
3214 except AttributeError:
3216 except AttributeError:
3215 ct = {}
3217 ct = {}
3216 modcmds = set([c.split('|', 1)[0] for c in ct])
3218 modcmds = set([c.split('|', 1)[0] for c in ct])
3217 helplist(modcmds.__contains__)
3219 helplist(modcmds.__contains__)
3218 else:
3220 else:
3219 ui.write(_('use "hg help extensions" for information on enabling '
3221 ui.write(_('use "hg help extensions" for information on enabling '
3220 'extensions\n'))
3222 'extensions\n'))
3221
3223
3222 def helpextcmd(name):
3224 def helpextcmd(name):
3223 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
3225 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
3224 doc = gettext(mod.__doc__).splitlines()[0]
3226 doc = gettext(mod.__doc__).splitlines()[0]
3225
3227
3226 msg = help.listexts(_("'%s' is provided by the following "
3228 msg = help.listexts(_("'%s' is provided by the following "
3227 "extension:") % cmd, {ext: doc}, indent=4)
3229 "extension:") % cmd, {ext: doc}, indent=4)
3228 ui.write(minirst.format(msg, textwidth))
3230 ui.write(minirst.format(msg, textwidth))
3229 ui.write('\n')
3231 ui.write('\n')
3230 ui.write(_('use "hg help extensions" for information on enabling '
3232 ui.write(_('use "hg help extensions" for information on enabling '
3231 'extensions\n'))
3233 'extensions\n'))
3232
3234
3233 if name and name != 'shortlist':
3235 if name and name != 'shortlist':
3234 i = None
3236 i = None
3235 if unknowncmd:
3237 if unknowncmd:
3236 queries = (helpextcmd,)
3238 queries = (helpextcmd,)
3237 elif opts.get('extension'):
3239 elif opts.get('extension'):
3238 queries = (helpext,)
3240 queries = (helpext,)
3239 elif opts.get('command'):
3241 elif opts.get('command'):
3240 queries = (helpcmd,)
3242 queries = (helpcmd,)
3241 else:
3243 else:
3242 queries = (helptopic, helpcmd, helpext, helpextcmd)
3244 queries = (helptopic, helpcmd, helpext, helpextcmd)
3243 for f in queries:
3245 for f in queries:
3244 try:
3246 try:
3245 f(name)
3247 f(name)
3246 i = None
3248 i = None
3247 break
3249 break
3248 except error.UnknownCommand, inst:
3250 except error.UnknownCommand, inst:
3249 i = inst
3251 i = inst
3250 if i:
3252 if i:
3251 raise i
3253 raise i
3252 else:
3254 else:
3253 # program name
3255 # program name
3254 ui.status(_("Mercurial Distributed SCM\n"))
3256 ui.status(_("Mercurial Distributed SCM\n"))
3255 ui.status('\n')
3257 ui.status('\n')
3256 helplist()
3258 helplist()
3257
3259
3258
3260
3259 @command('identify|id',
3261 @command('identify|id',
3260 [('r', 'rev', '',
3262 [('r', 'rev', '',
3261 _('identify the specified revision'), _('REV')),
3263 _('identify the specified revision'), _('REV')),
3262 ('n', 'num', None, _('show local revision number')),
3264 ('n', 'num', None, _('show local revision number')),
3263 ('i', 'id', None, _('show global revision id')),
3265 ('i', 'id', None, _('show global revision id')),
3264 ('b', 'branch', None, _('show branch')),
3266 ('b', 'branch', None, _('show branch')),
3265 ('t', 'tags', None, _('show tags')),
3267 ('t', 'tags', None, _('show tags')),
3266 ('B', 'bookmarks', None, _('show bookmarks')),
3268 ('B', 'bookmarks', None, _('show bookmarks')),
3267 ] + remoteopts,
3269 ] + remoteopts,
3268 _('[-nibtB] [-r REV] [SOURCE]'))
3270 _('[-nibtB] [-r REV] [SOURCE]'))
3269 def identify(ui, repo, source=None, rev=None,
3271 def identify(ui, repo, source=None, rev=None,
3270 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3272 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3271 """identify the working copy or specified revision
3273 """identify the working copy or specified revision
3272
3274
3273 Print a summary identifying the repository state at REV using one or
3275 Print a summary identifying the repository state at REV using one or
3274 two parent hash identifiers, followed by a "+" if the working
3276 two parent hash identifiers, followed by a "+" if the working
3275 directory has uncommitted changes, the branch name (if not default),
3277 directory has uncommitted changes, the branch name (if not default),
3276 a list of tags, and a list of bookmarks.
3278 a list of tags, and a list of bookmarks.
3277
3279
3278 When REV is not given, print a summary of the current state of the
3280 When REV is not given, print a summary of the current state of the
3279 repository.
3281 repository.
3280
3282
3281 Specifying a path to a repository root or Mercurial bundle will
3283 Specifying a path to a repository root or Mercurial bundle will
3282 cause lookup to operate on that repository/bundle.
3284 cause lookup to operate on that repository/bundle.
3283
3285
3284 .. container:: verbose
3286 .. container:: verbose
3285
3287
3286 Examples:
3288 Examples:
3287
3289
3288 - generate a build identifier for the working directory::
3290 - generate a build identifier for the working directory::
3289
3291
3290 hg id --id > build-id.dat
3292 hg id --id > build-id.dat
3291
3293
3292 - find the revision corresponding to a tag::
3294 - find the revision corresponding to a tag::
3293
3295
3294 hg id -n -r 1.3
3296 hg id -n -r 1.3
3295
3297
3296 - check the most recent revision of a remote repository::
3298 - check the most recent revision of a remote repository::
3297
3299
3298 hg id -r tip http://selenic.com/hg/
3300 hg id -r tip http://selenic.com/hg/
3299
3301
3300 Returns 0 if successful.
3302 Returns 0 if successful.
3301 """
3303 """
3302
3304
3303 if not repo and not source:
3305 if not repo and not source:
3304 raise util.Abort(_("there is no Mercurial repository here "
3306 raise util.Abort(_("there is no Mercurial repository here "
3305 "(.hg not found)"))
3307 "(.hg not found)"))
3306
3308
3307 hexfunc = ui.debugflag and hex or short
3309 hexfunc = ui.debugflag and hex or short
3308 default = not (num or id or branch or tags or bookmarks)
3310 default = not (num or id or branch or tags or bookmarks)
3309 output = []
3311 output = []
3310 revs = []
3312 revs = []
3311
3313
3312 if source:
3314 if source:
3313 source, branches = hg.parseurl(ui.expandpath(source))
3315 source, branches = hg.parseurl(ui.expandpath(source))
3314 repo = hg.peer(ui, opts, source)
3316 repo = hg.peer(ui, opts, source)
3315 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3317 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3316
3318
3317 if not repo.local():
3319 if not repo.local():
3318 if num or branch or tags:
3320 if num or branch or tags:
3319 raise util.Abort(
3321 raise util.Abort(
3320 _("can't query remote revision number, branch, or tags"))
3322 _("can't query remote revision number, branch, or tags"))
3321 if not rev and revs:
3323 if not rev and revs:
3322 rev = revs[0]
3324 rev = revs[0]
3323 if not rev:
3325 if not rev:
3324 rev = "tip"
3326 rev = "tip"
3325
3327
3326 remoterev = repo.lookup(rev)
3328 remoterev = repo.lookup(rev)
3327 if default or id:
3329 if default or id:
3328 output = [hexfunc(remoterev)]
3330 output = [hexfunc(remoterev)]
3329
3331
3330 def getbms():
3332 def getbms():
3331 bms = []
3333 bms = []
3332
3334
3333 if 'bookmarks' in repo.listkeys('namespaces'):
3335 if 'bookmarks' in repo.listkeys('namespaces'):
3334 hexremoterev = hex(remoterev)
3336 hexremoterev = hex(remoterev)
3335 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
3337 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
3336 if bmr == hexremoterev]
3338 if bmr == hexremoterev]
3337
3339
3338 return bms
3340 return bms
3339
3341
3340 if bookmarks:
3342 if bookmarks:
3341 output.extend(getbms())
3343 output.extend(getbms())
3342 elif default and not ui.quiet:
3344 elif default and not ui.quiet:
3343 # multiple bookmarks for a single parent separated by '/'
3345 # multiple bookmarks for a single parent separated by '/'
3344 bm = '/'.join(getbms())
3346 bm = '/'.join(getbms())
3345 if bm:
3347 if bm:
3346 output.append(bm)
3348 output.append(bm)
3347 else:
3349 else:
3348 if not rev:
3350 if not rev:
3349 ctx = repo[None]
3351 ctx = repo[None]
3350 parents = ctx.parents()
3352 parents = ctx.parents()
3351 changed = ""
3353 changed = ""
3352 if default or id or num:
3354 if default or id or num:
3353 changed = util.any(repo.status()) and "+" or ""
3355 changed = util.any(repo.status()) and "+" or ""
3354 if default or id:
3356 if default or id:
3355 output = ["%s%s" %
3357 output = ["%s%s" %
3356 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3358 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3357 if num:
3359 if num:
3358 output.append("%s%s" %
3360 output.append("%s%s" %
3359 ('+'.join([str(p.rev()) for p in parents]), changed))
3361 ('+'.join([str(p.rev()) for p in parents]), changed))
3360 else:
3362 else:
3361 ctx = scmutil.revsingle(repo, rev)
3363 ctx = scmutil.revsingle(repo, rev)
3362 if default or id:
3364 if default or id:
3363 output = [hexfunc(ctx.node())]
3365 output = [hexfunc(ctx.node())]
3364 if num:
3366 if num:
3365 output.append(str(ctx.rev()))
3367 output.append(str(ctx.rev()))
3366
3368
3367 if default and not ui.quiet:
3369 if default and not ui.quiet:
3368 b = ctx.branch()
3370 b = ctx.branch()
3369 if b != 'default':
3371 if b != 'default':
3370 output.append("(%s)" % b)
3372 output.append("(%s)" % b)
3371
3373
3372 # multiple tags for a single parent separated by '/'
3374 # multiple tags for a single parent separated by '/'
3373 t = '/'.join(ctx.tags())
3375 t = '/'.join(ctx.tags())
3374 if t:
3376 if t:
3375 output.append(t)
3377 output.append(t)
3376
3378
3377 # multiple bookmarks for a single parent separated by '/'
3379 # multiple bookmarks for a single parent separated by '/'
3378 bm = '/'.join(ctx.bookmarks())
3380 bm = '/'.join(ctx.bookmarks())
3379 if bm:
3381 if bm:
3380 output.append(bm)
3382 output.append(bm)
3381 else:
3383 else:
3382 if branch:
3384 if branch:
3383 output.append(ctx.branch())
3385 output.append(ctx.branch())
3384
3386
3385 if tags:
3387 if tags:
3386 output.extend(ctx.tags())
3388 output.extend(ctx.tags())
3387
3389
3388 if bookmarks:
3390 if bookmarks:
3389 output.extend(ctx.bookmarks())
3391 output.extend(ctx.bookmarks())
3390
3392
3391 ui.write("%s\n" % ' '.join(output))
3393 ui.write("%s\n" % ' '.join(output))
3392
3394
3393 @command('import|patch',
3395 @command('import|patch',
3394 [('p', 'strip', 1,
3396 [('p', 'strip', 1,
3395 _('directory strip option for patch. This has the same '
3397 _('directory strip option for patch. This has the same '
3396 'meaning as the corresponding patch option'), _('NUM')),
3398 'meaning as the corresponding patch option'), _('NUM')),
3397 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3399 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3398 ('e', 'edit', False, _('invoke editor on commit messages')),
3400 ('e', 'edit', False, _('invoke editor on commit messages')),
3399 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
3401 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
3400 ('', 'no-commit', None,
3402 ('', 'no-commit', None,
3401 _("don't commit, just update the working directory")),
3403 _("don't commit, just update the working directory")),
3402 ('', 'bypass', None,
3404 ('', 'bypass', None,
3403 _("apply patch without touching the working directory")),
3405 _("apply patch without touching the working directory")),
3404 ('', 'exact', None,
3406 ('', 'exact', None,
3405 _('apply patch to the nodes from which it was generated')),
3407 _('apply patch to the nodes from which it was generated')),
3406 ('', 'import-branch', None,
3408 ('', 'import-branch', None,
3407 _('use any branch information in patch (implied by --exact)'))] +
3409 _('use any branch information in patch (implied by --exact)'))] +
3408 commitopts + commitopts2 + similarityopts,
3410 commitopts + commitopts2 + similarityopts,
3409 _('[OPTION]... PATCH...'))
3411 _('[OPTION]... PATCH...'))
3410 def import_(ui, repo, patch1=None, *patches, **opts):
3412 def import_(ui, repo, patch1=None, *patches, **opts):
3411 """import an ordered set of patches
3413 """import an ordered set of patches
3412
3414
3413 Import a list of patches and commit them individually (unless
3415 Import a list of patches and commit them individually (unless
3414 --no-commit is specified).
3416 --no-commit is specified).
3415
3417
3416 If there are outstanding changes in the working directory, import
3418 If there are outstanding changes in the working directory, import
3417 will abort unless given the -f/--force flag.
3419 will abort unless given the -f/--force flag.
3418
3420
3419 You can import a patch straight from a mail message. Even patches
3421 You can import a patch straight from a mail message. Even patches
3420 as attachments work (to use the body part, it must have type
3422 as attachments work (to use the body part, it must have type
3421 text/plain or text/x-patch). From and Subject headers of email
3423 text/plain or text/x-patch). From and Subject headers of email
3422 message are used as default committer and commit message. All
3424 message are used as default committer and commit message. All
3423 text/plain body parts before first diff are added to commit
3425 text/plain body parts before first diff are added to commit
3424 message.
3426 message.
3425
3427
3426 If the imported patch was generated by :hg:`export`, user and
3428 If the imported patch was generated by :hg:`export`, user and
3427 description from patch override values from message headers and
3429 description from patch override values from message headers and
3428 body. Values given on command line with -m/--message and -u/--user
3430 body. Values given on command line with -m/--message and -u/--user
3429 override these.
3431 override these.
3430
3432
3431 If --exact is specified, import will set the working directory to
3433 If --exact is specified, import will set the working directory to
3432 the parent of each patch before applying it, and will abort if the
3434 the parent of each patch before applying it, and will abort if the
3433 resulting changeset has a different ID than the one recorded in
3435 resulting changeset has a different ID than the one recorded in
3434 the patch. This may happen due to character set problems or other
3436 the patch. This may happen due to character set problems or other
3435 deficiencies in the text patch format.
3437 deficiencies in the text patch format.
3436
3438
3437 Use --bypass to apply and commit patches directly to the
3439 Use --bypass to apply and commit patches directly to the
3438 repository, not touching the working directory. Without --exact,
3440 repository, not touching the working directory. Without --exact,
3439 patches will be applied on top of the working directory parent
3441 patches will be applied on top of the working directory parent
3440 revision.
3442 revision.
3441
3443
3442 With -s/--similarity, hg will attempt to discover renames and
3444 With -s/--similarity, hg will attempt to discover renames and
3443 copies in the patch in the same way as 'addremove'.
3445 copies in the patch in the same way as 'addremove'.
3444
3446
3445 To read a patch from standard input, use "-" as the patch name. If
3447 To read a patch from standard input, use "-" as the patch name. If
3446 a URL is specified, the patch will be downloaded from it.
3448 a URL is specified, the patch will be downloaded from it.
3447 See :hg:`help dates` for a list of formats valid for -d/--date.
3449 See :hg:`help dates` for a list of formats valid for -d/--date.
3448
3450
3449 .. container:: verbose
3451 .. container:: verbose
3450
3452
3451 Examples:
3453 Examples:
3452
3454
3453 - import a traditional patch from a website and detect renames::
3455 - import a traditional patch from a website and detect renames::
3454
3456
3455 hg import -s 80 http://example.com/bugfix.patch
3457 hg import -s 80 http://example.com/bugfix.patch
3456
3458
3457 - import a changeset from an hgweb server::
3459 - import a changeset from an hgweb server::
3458
3460
3459 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3461 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3460
3462
3461 - import all the patches in an Unix-style mbox::
3463 - import all the patches in an Unix-style mbox::
3462
3464
3463 hg import incoming-patches.mbox
3465 hg import incoming-patches.mbox
3464
3466
3465 - attempt to exactly restore an exported changeset (not always
3467 - attempt to exactly restore an exported changeset (not always
3466 possible)::
3468 possible)::
3467
3469
3468 hg import --exact proposed-fix.patch
3470 hg import --exact proposed-fix.patch
3469
3471
3470 Returns 0 on success.
3472 Returns 0 on success.
3471 """
3473 """
3472
3474
3473 if not patch1:
3475 if not patch1:
3474 raise util.Abort(_('need at least one patch to import'))
3476 raise util.Abort(_('need at least one patch to import'))
3475
3477
3476 patches = (patch1,) + patches
3478 patches = (patch1,) + patches
3477
3479
3478 date = opts.get('date')
3480 date = opts.get('date')
3479 if date:
3481 if date:
3480 opts['date'] = util.parsedate(date)
3482 opts['date'] = util.parsedate(date)
3481
3483
3482 editor = cmdutil.commiteditor
3484 editor = cmdutil.commiteditor
3483 if opts.get('edit'):
3485 if opts.get('edit'):
3484 editor = cmdutil.commitforceeditor
3486 editor = cmdutil.commitforceeditor
3485
3487
3486 update = not opts.get('bypass')
3488 update = not opts.get('bypass')
3487 if not update and opts.get('no_commit'):
3489 if not update and opts.get('no_commit'):
3488 raise util.Abort(_('cannot use --no-commit with --bypass'))
3490 raise util.Abort(_('cannot use --no-commit with --bypass'))
3489 try:
3491 try:
3490 sim = float(opts.get('similarity') or 0)
3492 sim = float(opts.get('similarity') or 0)
3491 except ValueError:
3493 except ValueError:
3492 raise util.Abort(_('similarity must be a number'))
3494 raise util.Abort(_('similarity must be a number'))
3493 if sim < 0 or sim > 100:
3495 if sim < 0 or sim > 100:
3494 raise util.Abort(_('similarity must be between 0 and 100'))
3496 raise util.Abort(_('similarity must be between 0 and 100'))
3495 if sim and not update:
3497 if sim and not update:
3496 raise util.Abort(_('cannot use --similarity with --bypass'))
3498 raise util.Abort(_('cannot use --similarity with --bypass'))
3497
3499
3498 if (opts.get('exact') or not opts.get('force')) and update:
3500 if (opts.get('exact') or not opts.get('force')) and update:
3499 cmdutil.bailifchanged(repo)
3501 cmdutil.bailifchanged(repo)
3500
3502
3501 base = opts["base"]
3503 base = opts["base"]
3502 strip = opts["strip"]
3504 strip = opts["strip"]
3503 wlock = lock = tr = None
3505 wlock = lock = tr = None
3504 msgs = []
3506 msgs = []
3505
3507
3506 def checkexact(repo, n, nodeid):
3508 def checkexact(repo, n, nodeid):
3507 if opts.get('exact') and hex(n) != nodeid:
3509 if opts.get('exact') and hex(n) != nodeid:
3508 repo.rollback()
3510 repo.rollback()
3509 raise util.Abort(_('patch is damaged or loses information'))
3511 raise util.Abort(_('patch is damaged or loses information'))
3510
3512
3511 def tryone(ui, hunk, parents):
3513 def tryone(ui, hunk, parents):
3512 tmpname, message, user, date, branch, nodeid, p1, p2 = \
3514 tmpname, message, user, date, branch, nodeid, p1, p2 = \
3513 patch.extract(ui, hunk)
3515 patch.extract(ui, hunk)
3514
3516
3515 if not tmpname:
3517 if not tmpname:
3516 return (None, None)
3518 return (None, None)
3517 msg = _('applied to working directory')
3519 msg = _('applied to working directory')
3518
3520
3519 try:
3521 try:
3520 cmdline_message = cmdutil.logmessage(ui, opts)
3522 cmdline_message = cmdutil.logmessage(ui, opts)
3521 if cmdline_message:
3523 if cmdline_message:
3522 # pickup the cmdline msg
3524 # pickup the cmdline msg
3523 message = cmdline_message
3525 message = cmdline_message
3524 elif message:
3526 elif message:
3525 # pickup the patch msg
3527 # pickup the patch msg
3526 message = message.strip()
3528 message = message.strip()
3527 else:
3529 else:
3528 # launch the editor
3530 # launch the editor
3529 message = None
3531 message = None
3530 ui.debug('message:\n%s\n' % message)
3532 ui.debug('message:\n%s\n' % message)
3531
3533
3532 if len(parents) == 1:
3534 if len(parents) == 1:
3533 parents.append(repo[nullid])
3535 parents.append(repo[nullid])
3534 if opts.get('exact'):
3536 if opts.get('exact'):
3535 if not nodeid or not p1:
3537 if not nodeid or not p1:
3536 raise util.Abort(_('not a Mercurial patch'))
3538 raise util.Abort(_('not a Mercurial patch'))
3537 p1 = repo[p1]
3539 p1 = repo[p1]
3538 p2 = repo[p2 or nullid]
3540 p2 = repo[p2 or nullid]
3539 elif p2:
3541 elif p2:
3540 try:
3542 try:
3541 p1 = repo[p1]
3543 p1 = repo[p1]
3542 p2 = repo[p2]
3544 p2 = repo[p2]
3543 # Without any options, consider p2 only if the
3545 # Without any options, consider p2 only if the
3544 # patch is being applied on top of the recorded
3546 # patch is being applied on top of the recorded
3545 # first parent.
3547 # first parent.
3546 if p1 != parents[0]:
3548 if p1 != parents[0]:
3547 p1 = parents[0]
3549 p1 = parents[0]
3548 p2 = repo[nullid]
3550 p2 = repo[nullid]
3549 except error.RepoError:
3551 except error.RepoError:
3550 p1, p2 = parents
3552 p1, p2 = parents
3551 else:
3553 else:
3552 p1, p2 = parents
3554 p1, p2 = parents
3553
3555
3554 n = None
3556 n = None
3555 if update:
3557 if update:
3556 if p1 != parents[0]:
3558 if p1 != parents[0]:
3557 hg.clean(repo, p1.node())
3559 hg.clean(repo, p1.node())
3558 if p2 != parents[1]:
3560 if p2 != parents[1]:
3559 repo.dirstate.setparents(p1.node(), p2.node())
3561 repo.dirstate.setparents(p1.node(), p2.node())
3560
3562
3561 if opts.get('exact') or opts.get('import_branch'):
3563 if opts.get('exact') or opts.get('import_branch'):
3562 repo.dirstate.setbranch(branch or 'default')
3564 repo.dirstate.setbranch(branch or 'default')
3563
3565
3564 files = set()
3566 files = set()
3565 patch.patch(ui, repo, tmpname, strip=strip, files=files,
3567 patch.patch(ui, repo, tmpname, strip=strip, files=files,
3566 eolmode=None, similarity=sim / 100.0)
3568 eolmode=None, similarity=sim / 100.0)
3567 files = list(files)
3569 files = list(files)
3568 if opts.get('no_commit'):
3570 if opts.get('no_commit'):
3569 if message:
3571 if message:
3570 msgs.append(message)
3572 msgs.append(message)
3571 else:
3573 else:
3572 if opts.get('exact') or p2:
3574 if opts.get('exact') or p2:
3573 # If you got here, you either use --force and know what
3575 # If you got here, you either use --force and know what
3574 # you are doing or used --exact or a merge patch while
3576 # you are doing or used --exact or a merge patch while
3575 # being updated to its first parent.
3577 # being updated to its first parent.
3576 m = None
3578 m = None
3577 else:
3579 else:
3578 m = scmutil.matchfiles(repo, files or [])
3580 m = scmutil.matchfiles(repo, files or [])
3579 n = repo.commit(message, opts.get('user') or user,
3581 n = repo.commit(message, opts.get('user') or user,
3580 opts.get('date') or date, match=m,
3582 opts.get('date') or date, match=m,
3581 editor=editor)
3583 editor=editor)
3582 checkexact(repo, n, nodeid)
3584 checkexact(repo, n, nodeid)
3583 else:
3585 else:
3584 if opts.get('exact') or opts.get('import_branch'):
3586 if opts.get('exact') or opts.get('import_branch'):
3585 branch = branch or 'default'
3587 branch = branch or 'default'
3586 else:
3588 else:
3587 branch = p1.branch()
3589 branch = p1.branch()
3588 store = patch.filestore()
3590 store = patch.filestore()
3589 try:
3591 try:
3590 files = set()
3592 files = set()
3591 try:
3593 try:
3592 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
3594 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
3593 files, eolmode=None)
3595 files, eolmode=None)
3594 except patch.PatchError, e:
3596 except patch.PatchError, e:
3595 raise util.Abort(str(e))
3597 raise util.Abort(str(e))
3596 memctx = patch.makememctx(repo, (p1.node(), p2.node()),
3598 memctx = patch.makememctx(repo, (p1.node(), p2.node()),
3597 message,
3599 message,
3598 opts.get('user') or user,
3600 opts.get('user') or user,
3599 opts.get('date') or date,
3601 opts.get('date') or date,
3600 branch, files, store,
3602 branch, files, store,
3601 editor=cmdutil.commiteditor)
3603 editor=cmdutil.commiteditor)
3602 repo.savecommitmessage(memctx.description())
3604 repo.savecommitmessage(memctx.description())
3603 n = memctx.commit()
3605 n = memctx.commit()
3604 checkexact(repo, n, nodeid)
3606 checkexact(repo, n, nodeid)
3605 finally:
3607 finally:
3606 store.close()
3608 store.close()
3607 if n:
3609 if n:
3608 # i18n: refers to a short changeset id
3610 # i18n: refers to a short changeset id
3609 msg = _('created %s') % short(n)
3611 msg = _('created %s') % short(n)
3610 return (msg, n)
3612 return (msg, n)
3611 finally:
3613 finally:
3612 os.unlink(tmpname)
3614 os.unlink(tmpname)
3613
3615
3614 try:
3616 try:
3615 try:
3617 try:
3616 wlock = repo.wlock()
3618 wlock = repo.wlock()
3617 lock = repo.lock()
3619 lock = repo.lock()
3618 tr = repo.transaction('import')
3620 tr = repo.transaction('import')
3619 parents = repo.parents()
3621 parents = repo.parents()
3620 for patchurl in patches:
3622 for patchurl in patches:
3621 if patchurl == '-':
3623 if patchurl == '-':
3622 ui.status(_('applying patch from stdin\n'))
3624 ui.status(_('applying patch from stdin\n'))
3623 patchfile = ui.fin
3625 patchfile = ui.fin
3624 patchurl = 'stdin' # for error message
3626 patchurl = 'stdin' # for error message
3625 else:
3627 else:
3626 patchurl = os.path.join(base, patchurl)
3628 patchurl = os.path.join(base, patchurl)
3627 ui.status(_('applying %s\n') % patchurl)
3629 ui.status(_('applying %s\n') % patchurl)
3628 patchfile = url.open(ui, patchurl)
3630 patchfile = url.open(ui, patchurl)
3629
3631
3630 haspatch = False
3632 haspatch = False
3631 for hunk in patch.split(patchfile):
3633 for hunk in patch.split(patchfile):
3632 (msg, node) = tryone(ui, hunk, parents)
3634 (msg, node) = tryone(ui, hunk, parents)
3633 if msg:
3635 if msg:
3634 haspatch = True
3636 haspatch = True
3635 ui.note(msg + '\n')
3637 ui.note(msg + '\n')
3636 if update or opts.get('exact'):
3638 if update or opts.get('exact'):
3637 parents = repo.parents()
3639 parents = repo.parents()
3638 else:
3640 else:
3639 parents = [repo[node]]
3641 parents = [repo[node]]
3640
3642
3641 if not haspatch:
3643 if not haspatch:
3642 raise util.Abort(_('%s: no diffs found') % patchurl)
3644 raise util.Abort(_('%s: no diffs found') % patchurl)
3643
3645
3644 tr.close()
3646 tr.close()
3645 if msgs:
3647 if msgs:
3646 repo.savecommitmessage('\n* * *\n'.join(msgs))
3648 repo.savecommitmessage('\n* * *\n'.join(msgs))
3647 except:
3649 except:
3648 # wlock.release() indirectly calls dirstate.write(): since
3650 # wlock.release() indirectly calls dirstate.write(): since
3649 # we're crashing, we do not want to change the working dir
3651 # we're crashing, we do not want to change the working dir
3650 # parent after all, so make sure it writes nothing
3652 # parent after all, so make sure it writes nothing
3651 repo.dirstate.invalidate()
3653 repo.dirstate.invalidate()
3652 raise
3654 raise
3653 finally:
3655 finally:
3654 if tr:
3656 if tr:
3655 tr.release()
3657 tr.release()
3656 release(lock, wlock)
3658 release(lock, wlock)
3657
3659
3658 @command('incoming|in',
3660 @command('incoming|in',
3659 [('f', 'force', None,
3661 [('f', 'force', None,
3660 _('run even if remote repository is unrelated')),
3662 _('run even if remote repository is unrelated')),
3661 ('n', 'newest-first', None, _('show newest record first')),
3663 ('n', 'newest-first', None, _('show newest record first')),
3662 ('', 'bundle', '',
3664 ('', 'bundle', '',
3663 _('file to store the bundles into'), _('FILE')),
3665 _('file to store the bundles into'), _('FILE')),
3664 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3666 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3665 ('B', 'bookmarks', False, _("compare bookmarks")),
3667 ('B', 'bookmarks', False, _("compare bookmarks")),
3666 ('b', 'branch', [],
3668 ('b', 'branch', [],
3667 _('a specific branch you would like to pull'), _('BRANCH')),
3669 _('a specific branch you would like to pull'), _('BRANCH')),
3668 ] + logopts + remoteopts + subrepoopts,
3670 ] + logopts + remoteopts + subrepoopts,
3669 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3671 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3670 def incoming(ui, repo, source="default", **opts):
3672 def incoming(ui, repo, source="default", **opts):
3671 """show new changesets found in source
3673 """show new changesets found in source
3672
3674
3673 Show new changesets found in the specified path/URL or the default
3675 Show new changesets found in the specified path/URL or the default
3674 pull location. These are the changesets that would have been pulled
3676 pull location. These are the changesets that would have been pulled
3675 if a pull at the time you issued this command.
3677 if a pull at the time you issued this command.
3676
3678
3677 For remote repository, using --bundle avoids downloading the
3679 For remote repository, using --bundle avoids downloading the
3678 changesets twice if the incoming is followed by a pull.
3680 changesets twice if the incoming is followed by a pull.
3679
3681
3680 See pull for valid source format details.
3682 See pull for valid source format details.
3681
3683
3682 Returns 0 if there are incoming changes, 1 otherwise.
3684 Returns 0 if there are incoming changes, 1 otherwise.
3683 """
3685 """
3684 if opts.get('bundle') and opts.get('subrepos'):
3686 if opts.get('bundle') and opts.get('subrepos'):
3685 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3687 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3686
3688
3687 if opts.get('bookmarks'):
3689 if opts.get('bookmarks'):
3688 source, branches = hg.parseurl(ui.expandpath(source),
3690 source, branches = hg.parseurl(ui.expandpath(source),
3689 opts.get('branch'))
3691 opts.get('branch'))
3690 other = hg.peer(repo, opts, source)
3692 other = hg.peer(repo, opts, source)
3691 if 'bookmarks' not in other.listkeys('namespaces'):
3693 if 'bookmarks' not in other.listkeys('namespaces'):
3692 ui.warn(_("remote doesn't support bookmarks\n"))
3694 ui.warn(_("remote doesn't support bookmarks\n"))
3693 return 0
3695 return 0
3694 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3696 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3695 return bookmarks.diff(ui, repo, other)
3697 return bookmarks.diff(ui, repo, other)
3696
3698
3697 repo._subtoppath = ui.expandpath(source)
3699 repo._subtoppath = ui.expandpath(source)
3698 try:
3700 try:
3699 return hg.incoming(ui, repo, source, opts)
3701 return hg.incoming(ui, repo, source, opts)
3700 finally:
3702 finally:
3701 del repo._subtoppath
3703 del repo._subtoppath
3702
3704
3703
3705
3704 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3706 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3705 def init(ui, dest=".", **opts):
3707 def init(ui, dest=".", **opts):
3706 """create a new repository in the given directory
3708 """create a new repository in the given directory
3707
3709
3708 Initialize a new repository in the given directory. If the given
3710 Initialize a new repository in the given directory. If the given
3709 directory does not exist, it will be created.
3711 directory does not exist, it will be created.
3710
3712
3711 If no directory is given, the current directory is used.
3713 If no directory is given, the current directory is used.
3712
3714
3713 It is possible to specify an ``ssh://`` URL as the destination.
3715 It is possible to specify an ``ssh://`` URL as the destination.
3714 See :hg:`help urls` for more information.
3716 See :hg:`help urls` for more information.
3715
3717
3716 Returns 0 on success.
3718 Returns 0 on success.
3717 """
3719 """
3718 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3720 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3719
3721
3720 @command('locate',
3722 @command('locate',
3721 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3723 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3722 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3724 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3723 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3725 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3724 ] + walkopts,
3726 ] + walkopts,
3725 _('[OPTION]... [PATTERN]...'))
3727 _('[OPTION]... [PATTERN]...'))
3726 def locate(ui, repo, *pats, **opts):
3728 def locate(ui, repo, *pats, **opts):
3727 """locate files matching specific patterns
3729 """locate files matching specific patterns
3728
3730
3729 Print files under Mercurial control in the working directory whose
3731 Print files under Mercurial control in the working directory whose
3730 names match the given patterns.
3732 names match the given patterns.
3731
3733
3732 By default, this command searches all directories in the working
3734 By default, this command searches all directories in the working
3733 directory. To search just the current directory and its
3735 directory. To search just the current directory and its
3734 subdirectories, use "--include .".
3736 subdirectories, use "--include .".
3735
3737
3736 If no patterns are given to match, this command prints the names
3738 If no patterns are given to match, this command prints the names
3737 of all files under Mercurial control in the working directory.
3739 of all files under Mercurial control in the working directory.
3738
3740
3739 If you want to feed the output of this command into the "xargs"
3741 If you want to feed the output of this command into the "xargs"
3740 command, use the -0 option to both this command and "xargs". This
3742 command, use the -0 option to both this command and "xargs". This
3741 will avoid the problem of "xargs" treating single filenames that
3743 will avoid the problem of "xargs" treating single filenames that
3742 contain whitespace as multiple filenames.
3744 contain whitespace as multiple filenames.
3743
3745
3744 Returns 0 if a match is found, 1 otherwise.
3746 Returns 0 if a match is found, 1 otherwise.
3745 """
3747 """
3746 end = opts.get('print0') and '\0' or '\n'
3748 end = opts.get('print0') and '\0' or '\n'
3747 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3749 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3748
3750
3749 ret = 1
3751 ret = 1
3750 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3752 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3751 m.bad = lambda x, y: False
3753 m.bad = lambda x, y: False
3752 for abs in repo[rev].walk(m):
3754 for abs in repo[rev].walk(m):
3753 if not rev and abs not in repo.dirstate:
3755 if not rev and abs not in repo.dirstate:
3754 continue
3756 continue
3755 if opts.get('fullpath'):
3757 if opts.get('fullpath'):
3756 ui.write(repo.wjoin(abs), end)
3758 ui.write(repo.wjoin(abs), end)
3757 else:
3759 else:
3758 ui.write(((pats and m.rel(abs)) or abs), end)
3760 ui.write(((pats and m.rel(abs)) or abs), end)
3759 ret = 0
3761 ret = 0
3760
3762
3761 return ret
3763 return ret
3762
3764
3763 @command('^log|history',
3765 @command('^log|history',
3764 [('f', 'follow', None,
3766 [('f', 'follow', None,
3765 _('follow changeset history, or file history across copies and renames')),
3767 _('follow changeset history, or file history across copies and renames')),
3766 ('', 'follow-first', None,
3768 ('', 'follow-first', None,
3767 _('only follow the first parent of merge changesets (DEPRECATED)')),
3769 _('only follow the first parent of merge changesets (DEPRECATED)')),
3768 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3770 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3769 ('C', 'copies', None, _('show copied files')),
3771 ('C', 'copies', None, _('show copied files')),
3770 ('k', 'keyword', [],
3772 ('k', 'keyword', [],
3771 _('do case-insensitive search for a given text'), _('TEXT')),
3773 _('do case-insensitive search for a given text'), _('TEXT')),
3772 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3774 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3773 ('', 'removed', None, _('include revisions where files were removed')),
3775 ('', 'removed', None, _('include revisions where files were removed')),
3774 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3776 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3775 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3777 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3776 ('', 'only-branch', [],
3778 ('', 'only-branch', [],
3777 _('show only changesets within the given named branch (DEPRECATED)'),
3779 _('show only changesets within the given named branch (DEPRECATED)'),
3778 _('BRANCH')),
3780 _('BRANCH')),
3779 ('b', 'branch', [],
3781 ('b', 'branch', [],
3780 _('show changesets within the given named branch'), _('BRANCH')),
3782 _('show changesets within the given named branch'), _('BRANCH')),
3781 ('P', 'prune', [],
3783 ('P', 'prune', [],
3782 _('do not display revision or any of its ancestors'), _('REV')),
3784 _('do not display revision or any of its ancestors'), _('REV')),
3783 ('', 'hidden', False, _('show hidden changesets (DEPRECATED)')),
3785 ('', 'hidden', False, _('show hidden changesets (DEPRECATED)')),
3784 ] + logopts + walkopts,
3786 ] + logopts + walkopts,
3785 _('[OPTION]... [FILE]'))
3787 _('[OPTION]... [FILE]'))
3786 def log(ui, repo, *pats, **opts):
3788 def log(ui, repo, *pats, **opts):
3787 """show revision history of entire repository or files
3789 """show revision history of entire repository or files
3788
3790
3789 Print the revision history of the specified files or the entire
3791 Print the revision history of the specified files or the entire
3790 project.
3792 project.
3791
3793
3792 If no revision range is specified, the default is ``tip:0`` unless
3794 If no revision range is specified, the default is ``tip:0`` unless
3793 --follow is set, in which case the working directory parent is
3795 --follow is set, in which case the working directory parent is
3794 used as the starting revision.
3796 used as the starting revision.
3795
3797
3796 File history is shown without following rename or copy history of
3798 File history is shown without following rename or copy history of
3797 files. Use -f/--follow with a filename to follow history across
3799 files. Use -f/--follow with a filename to follow history across
3798 renames and copies. --follow without a filename will only show
3800 renames and copies. --follow without a filename will only show
3799 ancestors or descendants of the starting revision.
3801 ancestors or descendants of the starting revision.
3800
3802
3801 By default this command prints revision number and changeset id,
3803 By default this command prints revision number and changeset id,
3802 tags, non-trivial parents, user, date and time, and a summary for
3804 tags, non-trivial parents, user, date and time, and a summary for
3803 each commit. When the -v/--verbose switch is used, the list of
3805 each commit. When the -v/--verbose switch is used, the list of
3804 changed files and full commit message are shown.
3806 changed files and full commit message are shown.
3805
3807
3806 .. note::
3808 .. note::
3807 log -p/--patch may generate unexpected diff output for merge
3809 log -p/--patch may generate unexpected diff output for merge
3808 changesets, as it will only compare the merge changeset against
3810 changesets, as it will only compare the merge changeset against
3809 its first parent. Also, only files different from BOTH parents
3811 its first parent. Also, only files different from BOTH parents
3810 will appear in files:.
3812 will appear in files:.
3811
3813
3812 .. note::
3814 .. note::
3813 for performance reasons, log FILE may omit duplicate changes
3815 for performance reasons, log FILE may omit duplicate changes
3814 made on branches and will not show deletions. To see all
3816 made on branches and will not show deletions. To see all
3815 changes including duplicates and deletions, use the --removed
3817 changes including duplicates and deletions, use the --removed
3816 switch.
3818 switch.
3817
3819
3818 .. container:: verbose
3820 .. container:: verbose
3819
3821
3820 Some examples:
3822 Some examples:
3821
3823
3822 - changesets with full descriptions and file lists::
3824 - changesets with full descriptions and file lists::
3823
3825
3824 hg log -v
3826 hg log -v
3825
3827
3826 - changesets ancestral to the working directory::
3828 - changesets ancestral to the working directory::
3827
3829
3828 hg log -f
3830 hg log -f
3829
3831
3830 - last 10 commits on the current branch::
3832 - last 10 commits on the current branch::
3831
3833
3832 hg log -l 10 -b .
3834 hg log -l 10 -b .
3833
3835
3834 - changesets showing all modifications of a file, including removals::
3836 - changesets showing all modifications of a file, including removals::
3835
3837
3836 hg log --removed file.c
3838 hg log --removed file.c
3837
3839
3838 - all changesets that touch a directory, with diffs, excluding merges::
3840 - all changesets that touch a directory, with diffs, excluding merges::
3839
3841
3840 hg log -Mp lib/
3842 hg log -Mp lib/
3841
3843
3842 - all revision numbers that match a keyword::
3844 - all revision numbers that match a keyword::
3843
3845
3844 hg log -k bug --template "{rev}\\n"
3846 hg log -k bug --template "{rev}\\n"
3845
3847
3846 - check if a given changeset is included is a tagged release::
3848 - check if a given changeset is included is a tagged release::
3847
3849
3848 hg log -r "a21ccf and ancestor(1.9)"
3850 hg log -r "a21ccf and ancestor(1.9)"
3849
3851
3850 - find all changesets by some user in a date range::
3852 - find all changesets by some user in a date range::
3851
3853
3852 hg log -k alice -d "may 2008 to jul 2008"
3854 hg log -k alice -d "may 2008 to jul 2008"
3853
3855
3854 - summary of all changesets after the last tag::
3856 - summary of all changesets after the last tag::
3855
3857
3856 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3858 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3857
3859
3858 See :hg:`help dates` for a list of formats valid for -d/--date.
3860 See :hg:`help dates` for a list of formats valid for -d/--date.
3859
3861
3860 See :hg:`help revisions` and :hg:`help revsets` for more about
3862 See :hg:`help revisions` and :hg:`help revsets` for more about
3861 specifying revisions.
3863 specifying revisions.
3862
3864
3863 Returns 0 on success.
3865 Returns 0 on success.
3864 """
3866 """
3865
3867
3866 matchfn = scmutil.match(repo[None], pats, opts)
3868 matchfn = scmutil.match(repo[None], pats, opts)
3867 limit = cmdutil.loglimit(opts)
3869 limit = cmdutil.loglimit(opts)
3868 count = 0
3870 count = 0
3869
3871
3870 endrev = None
3872 endrev = None
3871 if opts.get('copies') and opts.get('rev'):
3873 if opts.get('copies') and opts.get('rev'):
3872 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
3874 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
3873
3875
3874 df = False
3876 df = False
3875 if opts["date"]:
3877 if opts["date"]:
3876 df = util.matchdate(opts["date"])
3878 df = util.matchdate(opts["date"])
3877
3879
3878 branches = opts.get('branch', []) + opts.get('only_branch', [])
3880 branches = opts.get('branch', []) + opts.get('only_branch', [])
3879 opts['branch'] = [repo.lookupbranch(b) for b in branches]
3881 opts['branch'] = [repo.lookupbranch(b) for b in branches]
3880
3882
3881 displayer = cmdutil.show_changeset(ui, repo, opts, True)
3883 displayer = cmdutil.show_changeset(ui, repo, opts, True)
3882 def prep(ctx, fns):
3884 def prep(ctx, fns):
3883 rev = ctx.rev()
3885 rev = ctx.rev()
3884 parents = [p for p in repo.changelog.parentrevs(rev)
3886 parents = [p for p in repo.changelog.parentrevs(rev)
3885 if p != nullrev]
3887 if p != nullrev]
3886 if opts.get('no_merges') and len(parents) == 2:
3888 if opts.get('no_merges') and len(parents) == 2:
3887 return
3889 return
3888 if opts.get('only_merges') and len(parents) != 2:
3890 if opts.get('only_merges') and len(parents) != 2:
3889 return
3891 return
3890 if opts.get('branch') and ctx.branch() not in opts['branch']:
3892 if opts.get('branch') and ctx.branch() not in opts['branch']:
3891 return
3893 return
3892 if not opts.get('hidden') and ctx.hidden():
3894 if not opts.get('hidden') and ctx.hidden():
3893 return
3895 return
3894 if df and not df(ctx.date()[0]):
3896 if df and not df(ctx.date()[0]):
3895 return
3897 return
3896 if opts['user'] and not [k for k in opts['user']
3898 if opts['user'] and not [k for k in opts['user']
3897 if k.lower() in ctx.user().lower()]:
3899 if k.lower() in ctx.user().lower()]:
3898 return
3900 return
3899 if opts.get('keyword'):
3901 if opts.get('keyword'):
3900 for k in [kw.lower() for kw in opts['keyword']]:
3902 for k in [kw.lower() for kw in opts['keyword']]:
3901 if (k in ctx.user().lower() or
3903 if (k in ctx.user().lower() or
3902 k in ctx.description().lower() or
3904 k in ctx.description().lower() or
3903 k in " ".join(ctx.files()).lower()):
3905 k in " ".join(ctx.files()).lower()):
3904 break
3906 break
3905 else:
3907 else:
3906 return
3908 return
3907
3909
3908 copies = None
3910 copies = None
3909 if opts.get('copies') and rev:
3911 if opts.get('copies') and rev:
3910 copies = []
3912 copies = []
3911 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3913 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3912 for fn in ctx.files():
3914 for fn in ctx.files():
3913 rename = getrenamed(fn, rev)
3915 rename = getrenamed(fn, rev)
3914 if rename:
3916 if rename:
3915 copies.append((fn, rename[0]))
3917 copies.append((fn, rename[0]))
3916
3918
3917 revmatchfn = None
3919 revmatchfn = None
3918 if opts.get('patch') or opts.get('stat'):
3920 if opts.get('patch') or opts.get('stat'):
3919 if opts.get('follow') or opts.get('follow_first'):
3921 if opts.get('follow') or opts.get('follow_first'):
3920 # note: this might be wrong when following through merges
3922 # note: this might be wrong when following through merges
3921 revmatchfn = scmutil.match(repo[None], fns, default='path')
3923 revmatchfn = scmutil.match(repo[None], fns, default='path')
3922 else:
3924 else:
3923 revmatchfn = matchfn
3925 revmatchfn = matchfn
3924
3926
3925 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3927 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3926
3928
3927 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3929 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3928 if count == limit:
3930 if count == limit:
3929 break
3931 break
3930 if displayer.flush(ctx.rev()):
3932 if displayer.flush(ctx.rev()):
3931 count += 1
3933 count += 1
3932 displayer.close()
3934 displayer.close()
3933
3935
3934 @command('manifest',
3936 @command('manifest',
3935 [('r', 'rev', '', _('revision to display'), _('REV')),
3937 [('r', 'rev', '', _('revision to display'), _('REV')),
3936 ('', 'all', False, _("list files from all revisions"))],
3938 ('', 'all', False, _("list files from all revisions"))],
3937 _('[-r REV]'))
3939 _('[-r REV]'))
3938 def manifest(ui, repo, node=None, rev=None, **opts):
3940 def manifest(ui, repo, node=None, rev=None, **opts):
3939 """output the current or given revision of the project manifest
3941 """output the current or given revision of the project manifest
3940
3942
3941 Print a list of version controlled files for the given revision.
3943 Print a list of version controlled files for the given revision.
3942 If no revision is given, the first parent of the working directory
3944 If no revision is given, the first parent of the working directory
3943 is used, or the null revision if no revision is checked out.
3945 is used, or the null revision if no revision is checked out.
3944
3946
3945 With -v, print file permissions, symlink and executable bits.
3947 With -v, print file permissions, symlink and executable bits.
3946 With --debug, print file revision hashes.
3948 With --debug, print file revision hashes.
3947
3949
3948 If option --all is specified, the list of all files from all revisions
3950 If option --all is specified, the list of all files from all revisions
3949 is printed. This includes deleted and renamed files.
3951 is printed. This includes deleted and renamed files.
3950
3952
3951 Returns 0 on success.
3953 Returns 0 on success.
3952 """
3954 """
3953 if opts.get('all'):
3955 if opts.get('all'):
3954 if rev or node:
3956 if rev or node:
3955 raise util.Abort(_("can't specify a revision with --all"))
3957 raise util.Abort(_("can't specify a revision with --all"))
3956
3958
3957 res = []
3959 res = []
3958 prefix = "data/"
3960 prefix = "data/"
3959 suffix = ".i"
3961 suffix = ".i"
3960 plen = len(prefix)
3962 plen = len(prefix)
3961 slen = len(suffix)
3963 slen = len(suffix)
3962 lock = repo.lock()
3964 lock = repo.lock()
3963 try:
3965 try:
3964 for fn, b, size in repo.store.datafiles():
3966 for fn, b, size in repo.store.datafiles():
3965 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3967 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3966 res.append(fn[plen:-slen])
3968 res.append(fn[plen:-slen])
3967 finally:
3969 finally:
3968 lock.release()
3970 lock.release()
3969 for f in sorted(res):
3971 for f in sorted(res):
3970 ui.write("%s\n" % f)
3972 ui.write("%s\n" % f)
3971 return
3973 return
3972
3974
3973 if rev and node:
3975 if rev and node:
3974 raise util.Abort(_("please specify just one revision"))
3976 raise util.Abort(_("please specify just one revision"))
3975
3977
3976 if not node:
3978 if not node:
3977 node = rev
3979 node = rev
3978
3980
3979 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
3981 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
3980 ctx = scmutil.revsingle(repo, node)
3982 ctx = scmutil.revsingle(repo, node)
3981 for f in ctx:
3983 for f in ctx:
3982 if ui.debugflag:
3984 if ui.debugflag:
3983 ui.write("%40s " % hex(ctx.manifest()[f]))
3985 ui.write("%40s " % hex(ctx.manifest()[f]))
3984 if ui.verbose:
3986 if ui.verbose:
3985 ui.write(decor[ctx.flags(f)])
3987 ui.write(decor[ctx.flags(f)])
3986 ui.write("%s\n" % f)
3988 ui.write("%s\n" % f)
3987
3989
3988 @command('^merge',
3990 @command('^merge',
3989 [('f', 'force', None, _('force a merge with outstanding changes')),
3991 [('f', 'force', None, _('force a merge with outstanding changes')),
3990 ('r', 'rev', '', _('revision to merge'), _('REV')),
3992 ('r', 'rev', '', _('revision to merge'), _('REV')),
3991 ('P', 'preview', None,
3993 ('P', 'preview', None,
3992 _('review revisions to merge (no merge is performed)'))
3994 _('review revisions to merge (no merge is performed)'))
3993 ] + mergetoolopts,
3995 ] + mergetoolopts,
3994 _('[-P] [-f] [[-r] REV]'))
3996 _('[-P] [-f] [[-r] REV]'))
3995 def merge(ui, repo, node=None, **opts):
3997 def merge(ui, repo, node=None, **opts):
3996 """merge working directory with another revision
3998 """merge working directory with another revision
3997
3999
3998 The current working directory is updated with all changes made in
4000 The current working directory is updated with all changes made in
3999 the requested revision since the last common predecessor revision.
4001 the requested revision since the last common predecessor revision.
4000
4002
4001 Files that changed between either parent are marked as changed for
4003 Files that changed between either parent are marked as changed for
4002 the next commit and a commit must be performed before any further
4004 the next commit and a commit must be performed before any further
4003 updates to the repository are allowed. The next commit will have
4005 updates to the repository are allowed. The next commit will have
4004 two parents.
4006 two parents.
4005
4007
4006 ``--tool`` can be used to specify the merge tool used for file
4008 ``--tool`` can be used to specify the merge tool used for file
4007 merges. It overrides the HGMERGE environment variable and your
4009 merges. It overrides the HGMERGE environment variable and your
4008 configuration files. See :hg:`help merge-tools` for options.
4010 configuration files. See :hg:`help merge-tools` for options.
4009
4011
4010 If no revision is specified, the working directory's parent is a
4012 If no revision is specified, the working directory's parent is a
4011 head revision, and the current branch contains exactly one other
4013 head revision, and the current branch contains exactly one other
4012 head, the other head is merged with by default. Otherwise, an
4014 head, the other head is merged with by default. Otherwise, an
4013 explicit revision with which to merge with must be provided.
4015 explicit revision with which to merge with must be provided.
4014
4016
4015 :hg:`resolve` must be used to resolve unresolved files.
4017 :hg:`resolve` must be used to resolve unresolved files.
4016
4018
4017 To undo an uncommitted merge, use :hg:`update --clean .` which
4019 To undo an uncommitted merge, use :hg:`update --clean .` which
4018 will check out a clean copy of the original merge parent, losing
4020 will check out a clean copy of the original merge parent, losing
4019 all changes.
4021 all changes.
4020
4022
4021 Returns 0 on success, 1 if there are unresolved files.
4023 Returns 0 on success, 1 if there are unresolved files.
4022 """
4024 """
4023
4025
4024 if opts.get('rev') and node:
4026 if opts.get('rev') and node:
4025 raise util.Abort(_("please specify just one revision"))
4027 raise util.Abort(_("please specify just one revision"))
4026 if not node:
4028 if not node:
4027 node = opts.get('rev')
4029 node = opts.get('rev')
4028
4030
4029 if not node:
4031 if not node:
4030 branch = repo[None].branch()
4032 branch = repo[None].branch()
4031 bheads = repo.branchheads(branch)
4033 bheads = repo.branchheads(branch)
4032 if len(bheads) > 2:
4034 if len(bheads) > 2:
4033 raise util.Abort(_("branch '%s' has %d heads - "
4035 raise util.Abort(_("branch '%s' has %d heads - "
4034 "please merge with an explicit rev")
4036 "please merge with an explicit rev")
4035 % (branch, len(bheads)),
4037 % (branch, len(bheads)),
4036 hint=_("run 'hg heads .' to see heads"))
4038 hint=_("run 'hg heads .' to see heads"))
4037
4039
4038 parent = repo.dirstate.p1()
4040 parent = repo.dirstate.p1()
4039 if len(bheads) == 1:
4041 if len(bheads) == 1:
4040 if len(repo.heads()) > 1:
4042 if len(repo.heads()) > 1:
4041 raise util.Abort(_("branch '%s' has one head - "
4043 raise util.Abort(_("branch '%s' has one head - "
4042 "please merge with an explicit rev")
4044 "please merge with an explicit rev")
4043 % branch,
4045 % branch,
4044 hint=_("run 'hg heads' to see all heads"))
4046 hint=_("run 'hg heads' to see all heads"))
4045 msg, hint = _('nothing to merge'), None
4047 msg, hint = _('nothing to merge'), None
4046 if parent != repo.lookup(branch):
4048 if parent != repo.lookup(branch):
4047 hint = _("use 'hg update' instead")
4049 hint = _("use 'hg update' instead")
4048 raise util.Abort(msg, hint=hint)
4050 raise util.Abort(msg, hint=hint)
4049
4051
4050 if parent not in bheads:
4052 if parent not in bheads:
4051 raise util.Abort(_('working directory not at a head revision'),
4053 raise util.Abort(_('working directory not at a head revision'),
4052 hint=_("use 'hg update' or merge with an "
4054 hint=_("use 'hg update' or merge with an "
4053 "explicit revision"))
4055 "explicit revision"))
4054 node = parent == bheads[0] and bheads[-1] or bheads[0]
4056 node = parent == bheads[0] and bheads[-1] or bheads[0]
4055 else:
4057 else:
4056 node = scmutil.revsingle(repo, node).node()
4058 node = scmutil.revsingle(repo, node).node()
4057
4059
4058 if opts.get('preview'):
4060 if opts.get('preview'):
4059 # find nodes that are ancestors of p2 but not of p1
4061 # find nodes that are ancestors of p2 but not of p1
4060 p1 = repo.lookup('.')
4062 p1 = repo.lookup('.')
4061 p2 = repo.lookup(node)
4063 p2 = repo.lookup(node)
4062 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4064 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4063
4065
4064 displayer = cmdutil.show_changeset(ui, repo, opts)
4066 displayer = cmdutil.show_changeset(ui, repo, opts)
4065 for node in nodes:
4067 for node in nodes:
4066 displayer.show(repo[node])
4068 displayer.show(repo[node])
4067 displayer.close()
4069 displayer.close()
4068 return 0
4070 return 0
4069
4071
4070 try:
4072 try:
4071 # ui.forcemerge is an internal variable, do not document
4073 # ui.forcemerge is an internal variable, do not document
4072 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4074 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4073 return hg.merge(repo, node, force=opts.get('force'))
4075 return hg.merge(repo, node, force=opts.get('force'))
4074 finally:
4076 finally:
4075 ui.setconfig('ui', 'forcemerge', '')
4077 ui.setconfig('ui', 'forcemerge', '')
4076
4078
4077 @command('outgoing|out',
4079 @command('outgoing|out',
4078 [('f', 'force', None, _('run even when the destination is unrelated')),
4080 [('f', 'force', None, _('run even when the destination is unrelated')),
4079 ('r', 'rev', [],
4081 ('r', 'rev', [],
4080 _('a changeset intended to be included in the destination'), _('REV')),
4082 _('a changeset intended to be included in the destination'), _('REV')),
4081 ('n', 'newest-first', None, _('show newest record first')),
4083 ('n', 'newest-first', None, _('show newest record first')),
4082 ('B', 'bookmarks', False, _('compare bookmarks')),
4084 ('B', 'bookmarks', False, _('compare bookmarks')),
4083 ('b', 'branch', [], _('a specific branch you would like to push'),
4085 ('b', 'branch', [], _('a specific branch you would like to push'),
4084 _('BRANCH')),
4086 _('BRANCH')),
4085 ] + logopts + remoteopts + subrepoopts,
4087 ] + logopts + remoteopts + subrepoopts,
4086 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4088 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4087 def outgoing(ui, repo, dest=None, **opts):
4089 def outgoing(ui, repo, dest=None, **opts):
4088 """show changesets not found in the destination
4090 """show changesets not found in the destination
4089
4091
4090 Show changesets not found in the specified destination repository
4092 Show changesets not found in the specified destination repository
4091 or the default push location. These are the changesets that would
4093 or the default push location. These are the changesets that would
4092 be pushed if a push was requested.
4094 be pushed if a push was requested.
4093
4095
4094 See pull for details of valid destination formats.
4096 See pull for details of valid destination formats.
4095
4097
4096 Returns 0 if there are outgoing changes, 1 otherwise.
4098 Returns 0 if there are outgoing changes, 1 otherwise.
4097 """
4099 """
4098
4100
4099 if opts.get('bookmarks'):
4101 if opts.get('bookmarks'):
4100 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4102 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4101 dest, branches = hg.parseurl(dest, opts.get('branch'))
4103 dest, branches = hg.parseurl(dest, opts.get('branch'))
4102 other = hg.peer(repo, opts, dest)
4104 other = hg.peer(repo, opts, dest)
4103 if 'bookmarks' not in other.listkeys('namespaces'):
4105 if 'bookmarks' not in other.listkeys('namespaces'):
4104 ui.warn(_("remote doesn't support bookmarks\n"))
4106 ui.warn(_("remote doesn't support bookmarks\n"))
4105 return 0
4107 return 0
4106 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4108 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4107 return bookmarks.diff(ui, other, repo)
4109 return bookmarks.diff(ui, other, repo)
4108
4110
4109 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4111 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4110 try:
4112 try:
4111 return hg.outgoing(ui, repo, dest, opts)
4113 return hg.outgoing(ui, repo, dest, opts)
4112 finally:
4114 finally:
4113 del repo._subtoppath
4115 del repo._subtoppath
4114
4116
4115 @command('parents',
4117 @command('parents',
4116 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4118 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4117 ] + templateopts,
4119 ] + templateopts,
4118 _('[-r REV] [FILE]'))
4120 _('[-r REV] [FILE]'))
4119 def parents(ui, repo, file_=None, **opts):
4121 def parents(ui, repo, file_=None, **opts):
4120 """show the parents of the working directory or revision
4122 """show the parents of the working directory or revision
4121
4123
4122 Print the working directory's parent revisions. If a revision is
4124 Print the working directory's parent revisions. If a revision is
4123 given via -r/--rev, the parent of that revision will be printed.
4125 given via -r/--rev, the parent of that revision will be printed.
4124 If a file argument is given, the revision in which the file was
4126 If a file argument is given, the revision in which the file was
4125 last changed (before the working directory revision or the
4127 last changed (before the working directory revision or the
4126 argument to --rev if given) is printed.
4128 argument to --rev if given) is printed.
4127
4129
4128 Returns 0 on success.
4130 Returns 0 on success.
4129 """
4131 """
4130
4132
4131 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4133 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4132
4134
4133 if file_:
4135 if file_:
4134 m = scmutil.match(ctx, (file_,), opts)
4136 m = scmutil.match(ctx, (file_,), opts)
4135 if m.anypats() or len(m.files()) != 1:
4137 if m.anypats() or len(m.files()) != 1:
4136 raise util.Abort(_('can only specify an explicit filename'))
4138 raise util.Abort(_('can only specify an explicit filename'))
4137 file_ = m.files()[0]
4139 file_ = m.files()[0]
4138 filenodes = []
4140 filenodes = []
4139 for cp in ctx.parents():
4141 for cp in ctx.parents():
4140 if not cp:
4142 if not cp:
4141 continue
4143 continue
4142 try:
4144 try:
4143 filenodes.append(cp.filenode(file_))
4145 filenodes.append(cp.filenode(file_))
4144 except error.LookupError:
4146 except error.LookupError:
4145 pass
4147 pass
4146 if not filenodes:
4148 if not filenodes:
4147 raise util.Abort(_("'%s' not found in manifest!") % file_)
4149 raise util.Abort(_("'%s' not found in manifest!") % file_)
4148 fl = repo.file(file_)
4150 fl = repo.file(file_)
4149 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
4151 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
4150 else:
4152 else:
4151 p = [cp.node() for cp in ctx.parents()]
4153 p = [cp.node() for cp in ctx.parents()]
4152
4154
4153 displayer = cmdutil.show_changeset(ui, repo, opts)
4155 displayer = cmdutil.show_changeset(ui, repo, opts)
4154 for n in p:
4156 for n in p:
4155 if n != nullid:
4157 if n != nullid:
4156 displayer.show(repo[n])
4158 displayer.show(repo[n])
4157 displayer.close()
4159 displayer.close()
4158
4160
4159 @command('paths', [], _('[NAME]'))
4161 @command('paths', [], _('[NAME]'))
4160 def paths(ui, repo, search=None):
4162 def paths(ui, repo, search=None):
4161 """show aliases for remote repositories
4163 """show aliases for remote repositories
4162
4164
4163 Show definition of symbolic path name NAME. If no name is given,
4165 Show definition of symbolic path name NAME. If no name is given,
4164 show definition of all available names.
4166 show definition of all available names.
4165
4167
4166 Option -q/--quiet suppresses all output when searching for NAME
4168 Option -q/--quiet suppresses all output when searching for NAME
4167 and shows only the path names when listing all definitions.
4169 and shows only the path names when listing all definitions.
4168
4170
4169 Path names are defined in the [paths] section of your
4171 Path names are defined in the [paths] section of your
4170 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4172 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4171 repository, ``.hg/hgrc`` is used, too.
4173 repository, ``.hg/hgrc`` is used, too.
4172
4174
4173 The path names ``default`` and ``default-push`` have a special
4175 The path names ``default`` and ``default-push`` have a special
4174 meaning. When performing a push or pull operation, they are used
4176 meaning. When performing a push or pull operation, they are used
4175 as fallbacks if no location is specified on the command-line.
4177 as fallbacks if no location is specified on the command-line.
4176 When ``default-push`` is set, it will be used for push and
4178 When ``default-push`` is set, it will be used for push and
4177 ``default`` will be used for pull; otherwise ``default`` is used
4179 ``default`` will be used for pull; otherwise ``default`` is used
4178 as the fallback for both. When cloning a repository, the clone
4180 as the fallback for both. When cloning a repository, the clone
4179 source is written as ``default`` in ``.hg/hgrc``. Note that
4181 source is written as ``default`` in ``.hg/hgrc``. Note that
4180 ``default`` and ``default-push`` apply to all inbound (e.g.
4182 ``default`` and ``default-push`` apply to all inbound (e.g.
4181 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4183 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4182 :hg:`bundle`) operations.
4184 :hg:`bundle`) operations.
4183
4185
4184 See :hg:`help urls` for more information.
4186 See :hg:`help urls` for more information.
4185
4187
4186 Returns 0 on success.
4188 Returns 0 on success.
4187 """
4189 """
4188 if search:
4190 if search:
4189 for name, path in ui.configitems("paths"):
4191 for name, path in ui.configitems("paths"):
4190 if name == search:
4192 if name == search:
4191 ui.status("%s\n" % util.hidepassword(path))
4193 ui.status("%s\n" % util.hidepassword(path))
4192 return
4194 return
4193 if not ui.quiet:
4195 if not ui.quiet:
4194 ui.warn(_("not found!\n"))
4196 ui.warn(_("not found!\n"))
4195 return 1
4197 return 1
4196 else:
4198 else:
4197 for name, path in ui.configitems("paths"):
4199 for name, path in ui.configitems("paths"):
4198 if ui.quiet:
4200 if ui.quiet:
4199 ui.write("%s\n" % name)
4201 ui.write("%s\n" % name)
4200 else:
4202 else:
4201 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4203 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4202
4204
4203 def postincoming(ui, repo, modheads, optupdate, checkout):
4205 def postincoming(ui, repo, modheads, optupdate, checkout):
4204 if modheads == 0:
4206 if modheads == 0:
4205 return
4207 return
4206 if optupdate:
4208 if optupdate:
4207 try:
4209 try:
4208 return hg.update(repo, checkout)
4210 return hg.update(repo, checkout)
4209 except util.Abort, inst:
4211 except util.Abort, inst:
4210 ui.warn(_("not updating: %s\n" % str(inst)))
4212 ui.warn(_("not updating: %s\n" % str(inst)))
4211 return 0
4213 return 0
4212 if modheads > 1:
4214 if modheads > 1:
4213 currentbranchheads = len(repo.branchheads())
4215 currentbranchheads = len(repo.branchheads())
4214 if currentbranchheads == modheads:
4216 if currentbranchheads == modheads:
4215 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4217 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4216 elif currentbranchheads > 1:
4218 elif currentbranchheads > 1:
4217 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
4219 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
4218 else:
4220 else:
4219 ui.status(_("(run 'hg heads' to see heads)\n"))
4221 ui.status(_("(run 'hg heads' to see heads)\n"))
4220 else:
4222 else:
4221 ui.status(_("(run 'hg update' to get a working copy)\n"))
4223 ui.status(_("(run 'hg update' to get a working copy)\n"))
4222
4224
4223 @command('^pull',
4225 @command('^pull',
4224 [('u', 'update', None,
4226 [('u', 'update', None,
4225 _('update to new branch head if changesets were pulled')),
4227 _('update to new branch head if changesets were pulled')),
4226 ('f', 'force', None, _('run even when remote repository is unrelated')),
4228 ('f', 'force', None, _('run even when remote repository is unrelated')),
4227 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4229 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4228 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4230 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4229 ('b', 'branch', [], _('a specific branch you would like to pull'),
4231 ('b', 'branch', [], _('a specific branch you would like to pull'),
4230 _('BRANCH')),
4232 _('BRANCH')),
4231 ] + remoteopts,
4233 ] + remoteopts,
4232 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4234 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4233 def pull(ui, repo, source="default", **opts):
4235 def pull(ui, repo, source="default", **opts):
4234 """pull changes from the specified source
4236 """pull changes from the specified source
4235
4237
4236 Pull changes from a remote repository to a local one.
4238 Pull changes from a remote repository to a local one.
4237
4239
4238 This finds all changes from the repository at the specified path
4240 This finds all changes from the repository at the specified path
4239 or URL and adds them to a local repository (the current one unless
4241 or URL and adds them to a local repository (the current one unless
4240 -R is specified). By default, this does not update the copy of the
4242 -R is specified). By default, this does not update the copy of the
4241 project in the working directory.
4243 project in the working directory.
4242
4244
4243 Use :hg:`incoming` if you want to see what would have been added
4245 Use :hg:`incoming` if you want to see what would have been added
4244 by a pull at the time you issued this command. If you then decide
4246 by a pull at the time you issued this command. If you then decide
4245 to add those changes to the repository, you should use :hg:`pull
4247 to add those changes to the repository, you should use :hg:`pull
4246 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4248 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4247
4249
4248 If SOURCE is omitted, the 'default' path will be used.
4250 If SOURCE is omitted, the 'default' path will be used.
4249 See :hg:`help urls` for more information.
4251 See :hg:`help urls` for more information.
4250
4252
4251 Returns 0 on success, 1 if an update had unresolved files.
4253 Returns 0 on success, 1 if an update had unresolved files.
4252 """
4254 """
4253 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4255 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4254 other = hg.peer(repo, opts, source)
4256 other = hg.peer(repo, opts, source)
4255 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4257 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4256 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4258 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4257
4259
4258 if opts.get('bookmark'):
4260 if opts.get('bookmark'):
4259 if not revs:
4261 if not revs:
4260 revs = []
4262 revs = []
4261 rb = other.listkeys('bookmarks')
4263 rb = other.listkeys('bookmarks')
4262 for b in opts['bookmark']:
4264 for b in opts['bookmark']:
4263 if b not in rb:
4265 if b not in rb:
4264 raise util.Abort(_('remote bookmark %s not found!') % b)
4266 raise util.Abort(_('remote bookmark %s not found!') % b)
4265 revs.append(rb[b])
4267 revs.append(rb[b])
4266
4268
4267 if revs:
4269 if revs:
4268 try:
4270 try:
4269 revs = [other.lookup(rev) for rev in revs]
4271 revs = [other.lookup(rev) for rev in revs]
4270 except error.CapabilityError:
4272 except error.CapabilityError:
4271 err = _("other repository doesn't support revision lookup, "
4273 err = _("other repository doesn't support revision lookup, "
4272 "so a rev cannot be specified.")
4274 "so a rev cannot be specified.")
4273 raise util.Abort(err)
4275 raise util.Abort(err)
4274
4276
4275 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4277 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4276 bookmarks.updatefromremote(ui, repo, other, source)
4278 bookmarks.updatefromremote(ui, repo, other, source)
4277 if checkout:
4279 if checkout:
4278 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4280 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4279 repo._subtoppath = source
4281 repo._subtoppath = source
4280 try:
4282 try:
4281 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4283 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4282
4284
4283 finally:
4285 finally:
4284 del repo._subtoppath
4286 del repo._subtoppath
4285
4287
4286 # update specified bookmarks
4288 # update specified bookmarks
4287 if opts.get('bookmark'):
4289 if opts.get('bookmark'):
4288 for b in opts['bookmark']:
4290 for b in opts['bookmark']:
4289 # explicit pull overrides local bookmark if any
4291 # explicit pull overrides local bookmark if any
4290 ui.status(_("importing bookmark %s\n") % b)
4292 ui.status(_("importing bookmark %s\n") % b)
4291 repo._bookmarks[b] = repo[rb[b]].node()
4293 repo._bookmarks[b] = repo[rb[b]].node()
4292 bookmarks.write(repo)
4294 bookmarks.write(repo)
4293
4295
4294 return ret
4296 return ret
4295
4297
4296 @command('^push',
4298 @command('^push',
4297 [('f', 'force', None, _('force push')),
4299 [('f', 'force', None, _('force push')),
4298 ('r', 'rev', [],
4300 ('r', 'rev', [],
4299 _('a changeset intended to be included in the destination'),
4301 _('a changeset intended to be included in the destination'),
4300 _('REV')),
4302 _('REV')),
4301 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4303 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4302 ('b', 'branch', [],
4304 ('b', 'branch', [],
4303 _('a specific branch you would like to push'), _('BRANCH')),
4305 _('a specific branch you would like to push'), _('BRANCH')),
4304 ('', 'new-branch', False, _('allow pushing a new branch')),
4306 ('', 'new-branch', False, _('allow pushing a new branch')),
4305 ] + remoteopts,
4307 ] + remoteopts,
4306 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4308 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4307 def push(ui, repo, dest=None, **opts):
4309 def push(ui, repo, dest=None, **opts):
4308 """push changes to the specified destination
4310 """push changes to the specified destination
4309
4311
4310 Push changesets from the local repository to the specified
4312 Push changesets from the local repository to the specified
4311 destination.
4313 destination.
4312
4314
4313 This operation is symmetrical to pull: it is identical to a pull
4315 This operation is symmetrical to pull: it is identical to a pull
4314 in the destination repository from the current one.
4316 in the destination repository from the current one.
4315
4317
4316 By default, push will not allow creation of new heads at the
4318 By default, push will not allow creation of new heads at the
4317 destination, since multiple heads would make it unclear which head
4319 destination, since multiple heads would make it unclear which head
4318 to use. In this situation, it is recommended to pull and merge
4320 to use. In this situation, it is recommended to pull and merge
4319 before pushing.
4321 before pushing.
4320
4322
4321 Use --new-branch if you want to allow push to create a new named
4323 Use --new-branch if you want to allow push to create a new named
4322 branch that is not present at the destination. This allows you to
4324 branch that is not present at the destination. This allows you to
4323 only create a new branch without forcing other changes.
4325 only create a new branch without forcing other changes.
4324
4326
4325 Use -f/--force to override the default behavior and push all
4327 Use -f/--force to override the default behavior and push all
4326 changesets on all branches.
4328 changesets on all branches.
4327
4329
4328 If -r/--rev is used, the specified revision and all its ancestors
4330 If -r/--rev is used, the specified revision and all its ancestors
4329 will be pushed to the remote repository.
4331 will be pushed to the remote repository.
4330
4332
4331 Please see :hg:`help urls` for important details about ``ssh://``
4333 Please see :hg:`help urls` for important details about ``ssh://``
4332 URLs. If DESTINATION is omitted, a default path will be used.
4334 URLs. If DESTINATION is omitted, a default path will be used.
4333
4335
4334 Returns 0 if push was successful, 1 if nothing to push.
4336 Returns 0 if push was successful, 1 if nothing to push.
4335 """
4337 """
4336
4338
4337 if opts.get('bookmark'):
4339 if opts.get('bookmark'):
4338 for b in opts['bookmark']:
4340 for b in opts['bookmark']:
4339 # translate -B options to -r so changesets get pushed
4341 # translate -B options to -r so changesets get pushed
4340 if b in repo._bookmarks:
4342 if b in repo._bookmarks:
4341 opts.setdefault('rev', []).append(b)
4343 opts.setdefault('rev', []).append(b)
4342 else:
4344 else:
4343 # if we try to push a deleted bookmark, translate it to null
4345 # if we try to push a deleted bookmark, translate it to null
4344 # this lets simultaneous -r, -b options continue working
4346 # this lets simultaneous -r, -b options continue working
4345 opts.setdefault('rev', []).append("null")
4347 opts.setdefault('rev', []).append("null")
4346
4348
4347 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4349 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4348 dest, branches = hg.parseurl(dest, opts.get('branch'))
4350 dest, branches = hg.parseurl(dest, opts.get('branch'))
4349 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4351 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4350 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4352 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4351 other = hg.peer(repo, opts, dest)
4353 other = hg.peer(repo, opts, dest)
4352 if revs:
4354 if revs:
4353 revs = [repo.lookup(rev) for rev in revs]
4355 revs = [repo.lookup(rev) for rev in revs]
4354
4356
4355 repo._subtoppath = dest
4357 repo._subtoppath = dest
4356 try:
4358 try:
4357 # push subrepos depth-first for coherent ordering
4359 # push subrepos depth-first for coherent ordering
4358 c = repo['']
4360 c = repo['']
4359 subs = c.substate # only repos that are committed
4361 subs = c.substate # only repos that are committed
4360 for s in sorted(subs):
4362 for s in sorted(subs):
4361 if not c.sub(s).push(opts.get('force')):
4363 if not c.sub(s).push(opts.get('force')):
4362 return False
4364 return False
4363 finally:
4365 finally:
4364 del repo._subtoppath
4366 del repo._subtoppath
4365 result = repo.push(other, opts.get('force'), revs=revs,
4367 result = repo.push(other, opts.get('force'), revs=revs,
4366 newbranch=opts.get('new_branch'))
4368 newbranch=opts.get('new_branch'))
4367
4369
4368 result = (result == 0)
4370 result = (result == 0)
4369
4371
4370 if opts.get('bookmark'):
4372 if opts.get('bookmark'):
4371 rb = other.listkeys('bookmarks')
4373 rb = other.listkeys('bookmarks')
4372 for b in opts['bookmark']:
4374 for b in opts['bookmark']:
4373 # explicit push overrides remote bookmark if any
4375 # explicit push overrides remote bookmark if any
4374 if b in repo._bookmarks:
4376 if b in repo._bookmarks:
4375 ui.status(_("exporting bookmark %s\n") % b)
4377 ui.status(_("exporting bookmark %s\n") % b)
4376 new = repo[b].hex()
4378 new = repo[b].hex()
4377 elif b in rb:
4379 elif b in rb:
4378 ui.status(_("deleting remote bookmark %s\n") % b)
4380 ui.status(_("deleting remote bookmark %s\n") % b)
4379 new = '' # delete
4381 new = '' # delete
4380 else:
4382 else:
4381 ui.warn(_('bookmark %s does not exist on the local '
4383 ui.warn(_('bookmark %s does not exist on the local '
4382 'or remote repository!\n') % b)
4384 'or remote repository!\n') % b)
4383 return 2
4385 return 2
4384 old = rb.get(b, '')
4386 old = rb.get(b, '')
4385 r = other.pushkey('bookmarks', b, old, new)
4387 r = other.pushkey('bookmarks', b, old, new)
4386 if not r:
4388 if not r:
4387 ui.warn(_('updating bookmark %s failed!\n') % b)
4389 ui.warn(_('updating bookmark %s failed!\n') % b)
4388 if not result:
4390 if not result:
4389 result = 2
4391 result = 2
4390
4392
4391 return result
4393 return result
4392
4394
4393 @command('recover', [])
4395 @command('recover', [])
4394 def recover(ui, repo):
4396 def recover(ui, repo):
4395 """roll back an interrupted transaction
4397 """roll back an interrupted transaction
4396
4398
4397 Recover from an interrupted commit or pull.
4399 Recover from an interrupted commit or pull.
4398
4400
4399 This command tries to fix the repository status after an
4401 This command tries to fix the repository status after an
4400 interrupted operation. It should only be necessary when Mercurial
4402 interrupted operation. It should only be necessary when Mercurial
4401 suggests it.
4403 suggests it.
4402
4404
4403 Returns 0 if successful, 1 if nothing to recover or verify fails.
4405 Returns 0 if successful, 1 if nothing to recover or verify fails.
4404 """
4406 """
4405 if repo.recover():
4407 if repo.recover():
4406 return hg.verify(repo)
4408 return hg.verify(repo)
4407 return 1
4409 return 1
4408
4410
4409 @command('^remove|rm',
4411 @command('^remove|rm',
4410 [('A', 'after', None, _('record delete for missing files')),
4412 [('A', 'after', None, _('record delete for missing files')),
4411 ('f', 'force', None,
4413 ('f', 'force', None,
4412 _('remove (and delete) file even if added or modified')),
4414 _('remove (and delete) file even if added or modified')),
4413 ] + walkopts,
4415 ] + walkopts,
4414 _('[OPTION]... FILE...'))
4416 _('[OPTION]... FILE...'))
4415 def remove(ui, repo, *pats, **opts):
4417 def remove(ui, repo, *pats, **opts):
4416 """remove the specified files on the next commit
4418 """remove the specified files on the next commit
4417
4419
4418 Schedule the indicated files for removal from the current branch.
4420 Schedule the indicated files for removal from the current branch.
4419
4421
4420 This command schedules the files to be removed at the next commit.
4422 This command schedules the files to be removed at the next commit.
4421 To undo a remove before that, see :hg:`revert`. To undo added
4423 To undo a remove before that, see :hg:`revert`. To undo added
4422 files, see :hg:`forget`.
4424 files, see :hg:`forget`.
4423
4425
4424 .. container:: verbose
4426 .. container:: verbose
4425
4427
4426 -A/--after can be used to remove only files that have already
4428 -A/--after can be used to remove only files that have already
4427 been deleted, -f/--force can be used to force deletion, and -Af
4429 been deleted, -f/--force can be used to force deletion, and -Af
4428 can be used to remove files from the next revision without
4430 can be used to remove files from the next revision without
4429 deleting them from the working directory.
4431 deleting them from the working directory.
4430
4432
4431 The following table details the behavior of remove for different
4433 The following table details the behavior of remove for different
4432 file states (columns) and option combinations (rows). The file
4434 file states (columns) and option combinations (rows). The file
4433 states are Added [A], Clean [C], Modified [M] and Missing [!]
4435 states are Added [A], Clean [C], Modified [M] and Missing [!]
4434 (as reported by :hg:`status`). The actions are Warn, Remove
4436 (as reported by :hg:`status`). The actions are Warn, Remove
4435 (from branch) and Delete (from disk):
4437 (from branch) and Delete (from disk):
4436
4438
4437 ======= == == == ==
4439 ======= == == == ==
4438 A C M !
4440 A C M !
4439 ======= == == == ==
4441 ======= == == == ==
4440 none W RD W R
4442 none W RD W R
4441 -f R RD RD R
4443 -f R RD RD R
4442 -A W W W R
4444 -A W W W R
4443 -Af R R R R
4445 -Af R R R R
4444 ======= == == == ==
4446 ======= == == == ==
4445
4447
4446 Note that remove never deletes files in Added [A] state from the
4448 Note that remove never deletes files in Added [A] state from the
4447 working directory, not even if option --force is specified.
4449 working directory, not even if option --force is specified.
4448
4450
4449 Returns 0 on success, 1 if any warnings encountered.
4451 Returns 0 on success, 1 if any warnings encountered.
4450 """
4452 """
4451
4453
4452 ret = 0
4454 ret = 0
4453 after, force = opts.get('after'), opts.get('force')
4455 after, force = opts.get('after'), opts.get('force')
4454 if not pats and not after:
4456 if not pats and not after:
4455 raise util.Abort(_('no files specified'))
4457 raise util.Abort(_('no files specified'))
4456
4458
4457 m = scmutil.match(repo[None], pats, opts)
4459 m = scmutil.match(repo[None], pats, opts)
4458 s = repo.status(match=m, clean=True)
4460 s = repo.status(match=m, clean=True)
4459 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4461 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4460
4462
4461 for f in m.files():
4463 for f in m.files():
4462 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
4464 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
4463 if os.path.exists(m.rel(f)):
4465 if os.path.exists(m.rel(f)):
4464 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4466 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4465 ret = 1
4467 ret = 1
4466
4468
4467 if force:
4469 if force:
4468 list = modified + deleted + clean + added
4470 list = modified + deleted + clean + added
4469 elif after:
4471 elif after:
4470 list = deleted
4472 list = deleted
4471 for f in modified + added + clean:
4473 for f in modified + added + clean:
4472 ui.warn(_('not removing %s: file still exists (use -f'
4474 ui.warn(_('not removing %s: file still exists (use -f'
4473 ' to force removal)\n') % m.rel(f))
4475 ' to force removal)\n') % m.rel(f))
4474 ret = 1
4476 ret = 1
4475 else:
4477 else:
4476 list = deleted + clean
4478 list = deleted + clean
4477 for f in modified:
4479 for f in modified:
4478 ui.warn(_('not removing %s: file is modified (use -f'
4480 ui.warn(_('not removing %s: file is modified (use -f'
4479 ' to force removal)\n') % m.rel(f))
4481 ' to force removal)\n') % m.rel(f))
4480 ret = 1
4482 ret = 1
4481 for f in added:
4483 for f in added:
4482 ui.warn(_('not removing %s: file has been marked for add'
4484 ui.warn(_('not removing %s: file has been marked for add'
4483 ' (use forget to undo)\n') % m.rel(f))
4485 ' (use forget to undo)\n') % m.rel(f))
4484 ret = 1
4486 ret = 1
4485
4487
4486 for f in sorted(list):
4488 for f in sorted(list):
4487 if ui.verbose or not m.exact(f):
4489 if ui.verbose or not m.exact(f):
4488 ui.status(_('removing %s\n') % m.rel(f))
4490 ui.status(_('removing %s\n') % m.rel(f))
4489
4491
4490 wlock = repo.wlock()
4492 wlock = repo.wlock()
4491 try:
4493 try:
4492 if not after:
4494 if not after:
4493 for f in list:
4495 for f in list:
4494 if f in added:
4496 if f in added:
4495 continue # we never unlink added files on remove
4497 continue # we never unlink added files on remove
4496 try:
4498 try:
4497 util.unlinkpath(repo.wjoin(f))
4499 util.unlinkpath(repo.wjoin(f))
4498 except OSError, inst:
4500 except OSError, inst:
4499 if inst.errno != errno.ENOENT:
4501 if inst.errno != errno.ENOENT:
4500 raise
4502 raise
4501 repo[None].forget(list)
4503 repo[None].forget(list)
4502 finally:
4504 finally:
4503 wlock.release()
4505 wlock.release()
4504
4506
4505 return ret
4507 return ret
4506
4508
4507 @command('rename|move|mv',
4509 @command('rename|move|mv',
4508 [('A', 'after', None, _('record a rename that has already occurred')),
4510 [('A', 'after', None, _('record a rename that has already occurred')),
4509 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4511 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4510 ] + walkopts + dryrunopts,
4512 ] + walkopts + dryrunopts,
4511 _('[OPTION]... SOURCE... DEST'))
4513 _('[OPTION]... SOURCE... DEST'))
4512 def rename(ui, repo, *pats, **opts):
4514 def rename(ui, repo, *pats, **opts):
4513 """rename files; equivalent of copy + remove
4515 """rename files; equivalent of copy + remove
4514
4516
4515 Mark dest as copies of sources; mark sources for deletion. If dest
4517 Mark dest as copies of sources; mark sources for deletion. If dest
4516 is a directory, copies are put in that directory. If dest is a
4518 is a directory, copies are put in that directory. If dest is a
4517 file, there can only be one source.
4519 file, there can only be one source.
4518
4520
4519 By default, this command copies the contents of files as they
4521 By default, this command copies the contents of files as they
4520 exist in the working directory. If invoked with -A/--after, the
4522 exist in the working directory. If invoked with -A/--after, the
4521 operation is recorded, but no copying is performed.
4523 operation is recorded, but no copying is performed.
4522
4524
4523 This command takes effect at the next commit. To undo a rename
4525 This command takes effect at the next commit. To undo a rename
4524 before that, see :hg:`revert`.
4526 before that, see :hg:`revert`.
4525
4527
4526 Returns 0 on success, 1 if errors are encountered.
4528 Returns 0 on success, 1 if errors are encountered.
4527 """
4529 """
4528 wlock = repo.wlock(False)
4530 wlock = repo.wlock(False)
4529 try:
4531 try:
4530 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4532 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4531 finally:
4533 finally:
4532 wlock.release()
4534 wlock.release()
4533
4535
4534 @command('resolve',
4536 @command('resolve',
4535 [('a', 'all', None, _('select all unresolved files')),
4537 [('a', 'all', None, _('select all unresolved files')),
4536 ('l', 'list', None, _('list state of files needing merge')),
4538 ('l', 'list', None, _('list state of files needing merge')),
4537 ('m', 'mark', None, _('mark files as resolved')),
4539 ('m', 'mark', None, _('mark files as resolved')),
4538 ('u', 'unmark', None, _('mark files as unresolved')),
4540 ('u', 'unmark', None, _('mark files as unresolved')),
4539 ('n', 'no-status', None, _('hide status prefix'))]
4541 ('n', 'no-status', None, _('hide status prefix'))]
4540 + mergetoolopts + walkopts,
4542 + mergetoolopts + walkopts,
4541 _('[OPTION]... [FILE]...'))
4543 _('[OPTION]... [FILE]...'))
4542 def resolve(ui, repo, *pats, **opts):
4544 def resolve(ui, repo, *pats, **opts):
4543 """redo merges or set/view the merge status of files
4545 """redo merges or set/view the merge status of files
4544
4546
4545 Merges with unresolved conflicts are often the result of
4547 Merges with unresolved conflicts are often the result of
4546 non-interactive merging using the ``internal:merge`` configuration
4548 non-interactive merging using the ``internal:merge`` configuration
4547 setting, or a command-line merge tool like ``diff3``. The resolve
4549 setting, or a command-line merge tool like ``diff3``. The resolve
4548 command is used to manage the files involved in a merge, after
4550 command is used to manage the files involved in a merge, after
4549 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4551 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4550 working directory must have two parents).
4552 working directory must have two parents).
4551
4553
4552 The resolve command can be used in the following ways:
4554 The resolve command can be used in the following ways:
4553
4555
4554 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4556 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4555 files, discarding any previous merge attempts. Re-merging is not
4557 files, discarding any previous merge attempts. Re-merging is not
4556 performed for files already marked as resolved. Use ``--all/-a``
4558 performed for files already marked as resolved. Use ``--all/-a``
4557 to select all unresolved files. ``--tool`` can be used to specify
4559 to select all unresolved files. ``--tool`` can be used to specify
4558 the merge tool used for the given files. It overrides the HGMERGE
4560 the merge tool used for the given files. It overrides the HGMERGE
4559 environment variable and your configuration files. Previous file
4561 environment variable and your configuration files. Previous file
4560 contents are saved with a ``.orig`` suffix.
4562 contents are saved with a ``.orig`` suffix.
4561
4563
4562 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4564 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4563 (e.g. after having manually fixed-up the files). The default is
4565 (e.g. after having manually fixed-up the files). The default is
4564 to mark all unresolved files.
4566 to mark all unresolved files.
4565
4567
4566 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4568 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4567 default is to mark all resolved files.
4569 default is to mark all resolved files.
4568
4570
4569 - :hg:`resolve -l`: list files which had or still have conflicts.
4571 - :hg:`resolve -l`: list files which had or still have conflicts.
4570 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4572 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4571
4573
4572 Note that Mercurial will not let you commit files with unresolved
4574 Note that Mercurial will not let you commit files with unresolved
4573 merge conflicts. You must use :hg:`resolve -m ...` before you can
4575 merge conflicts. You must use :hg:`resolve -m ...` before you can
4574 commit after a conflicting merge.
4576 commit after a conflicting merge.
4575
4577
4576 Returns 0 on success, 1 if any files fail a resolve attempt.
4578 Returns 0 on success, 1 if any files fail a resolve attempt.
4577 """
4579 """
4578
4580
4579 all, mark, unmark, show, nostatus = \
4581 all, mark, unmark, show, nostatus = \
4580 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4582 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4581
4583
4582 if (show and (mark or unmark)) or (mark and unmark):
4584 if (show and (mark or unmark)) or (mark and unmark):
4583 raise util.Abort(_("too many options specified"))
4585 raise util.Abort(_("too many options specified"))
4584 if pats and all:
4586 if pats and all:
4585 raise util.Abort(_("can't specify --all and patterns"))
4587 raise util.Abort(_("can't specify --all and patterns"))
4586 if not (all or pats or show or mark or unmark):
4588 if not (all or pats or show or mark or unmark):
4587 raise util.Abort(_('no files or directories specified; '
4589 raise util.Abort(_('no files or directories specified; '
4588 'use --all to remerge all files'))
4590 'use --all to remerge all files'))
4589
4591
4590 ms = mergemod.mergestate(repo)
4592 ms = mergemod.mergestate(repo)
4591 m = scmutil.match(repo[None], pats, opts)
4593 m = scmutil.match(repo[None], pats, opts)
4592 ret = 0
4594 ret = 0
4593
4595
4594 for f in ms:
4596 for f in ms:
4595 if m(f):
4597 if m(f):
4596 if show:
4598 if show:
4597 if nostatus:
4599 if nostatus:
4598 ui.write("%s\n" % f)
4600 ui.write("%s\n" % f)
4599 else:
4601 else:
4600 ui.write("%s %s\n" % (ms[f].upper(), f),
4602 ui.write("%s %s\n" % (ms[f].upper(), f),
4601 label='resolve.' +
4603 label='resolve.' +
4602 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4604 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4603 elif mark:
4605 elif mark:
4604 ms.mark(f, "r")
4606 ms.mark(f, "r")
4605 elif unmark:
4607 elif unmark:
4606 ms.mark(f, "u")
4608 ms.mark(f, "u")
4607 else:
4609 else:
4608 wctx = repo[None]
4610 wctx = repo[None]
4609 mctx = wctx.parents()[-1]
4611 mctx = wctx.parents()[-1]
4610
4612
4611 # backup pre-resolve (merge uses .orig for its own purposes)
4613 # backup pre-resolve (merge uses .orig for its own purposes)
4612 a = repo.wjoin(f)
4614 a = repo.wjoin(f)
4613 util.copyfile(a, a + ".resolve")
4615 util.copyfile(a, a + ".resolve")
4614
4616
4615 try:
4617 try:
4616 # resolve file
4618 # resolve file
4617 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4619 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4618 if ms.resolve(f, wctx, mctx):
4620 if ms.resolve(f, wctx, mctx):
4619 ret = 1
4621 ret = 1
4620 finally:
4622 finally:
4621 ui.setconfig('ui', 'forcemerge', '')
4623 ui.setconfig('ui', 'forcemerge', '')
4622
4624
4623 # replace filemerge's .orig file with our resolve file
4625 # replace filemerge's .orig file with our resolve file
4624 util.rename(a + ".resolve", a + ".orig")
4626 util.rename(a + ".resolve", a + ".orig")
4625
4627
4626 ms.commit()
4628 ms.commit()
4627 return ret
4629 return ret
4628
4630
4629 @command('revert',
4631 @command('revert',
4630 [('a', 'all', None, _('revert all changes when no arguments given')),
4632 [('a', 'all', None, _('revert all changes when no arguments given')),
4631 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4633 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4632 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4634 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4633 ('C', 'no-backup', None, _('do not save backup copies of files')),
4635 ('C', 'no-backup', None, _('do not save backup copies of files')),
4634 ] + walkopts + dryrunopts,
4636 ] + walkopts + dryrunopts,
4635 _('[OPTION]... [-r REV] [NAME]...'))
4637 _('[OPTION]... [-r REV] [NAME]...'))
4636 def revert(ui, repo, *pats, **opts):
4638 def revert(ui, repo, *pats, **opts):
4637 """restore files to their checkout state
4639 """restore files to their checkout state
4638
4640
4639 .. note::
4641 .. note::
4640 To check out earlier revisions, you should use :hg:`update REV`.
4642 To check out earlier revisions, you should use :hg:`update REV`.
4641 To cancel a merge (and lose your changes), use :hg:`update --clean .`.
4643 To cancel a merge (and lose your changes), use :hg:`update --clean .`.
4642
4644
4643 With no revision specified, revert the specified files or directories
4645 With no revision specified, revert the specified files or directories
4644 to the contents they had in the parent of the working directory.
4646 to the contents they had in the parent of the working directory.
4645 This restores the contents of files to an unmodified
4647 This restores the contents of files to an unmodified
4646 state and unschedules adds, removes, copies, and renames. If the
4648 state and unschedules adds, removes, copies, and renames. If the
4647 working directory has two parents, you must explicitly specify a
4649 working directory has two parents, you must explicitly specify a
4648 revision.
4650 revision.
4649
4651
4650 Using the -r/--rev or -d/--date options, revert the given files or
4652 Using the -r/--rev or -d/--date options, revert the given files or
4651 directories to their states as of a specific revision. Because
4653 directories to their states as of a specific revision. Because
4652 revert does not change the working directory parents, this will
4654 revert does not change the working directory parents, this will
4653 cause these files to appear modified. This can be helpful to "back
4655 cause these files to appear modified. This can be helpful to "back
4654 out" some or all of an earlier change. See :hg:`backout` for a
4656 out" some or all of an earlier change. See :hg:`backout` for a
4655 related method.
4657 related method.
4656
4658
4657 Modified files are saved with a .orig suffix before reverting.
4659 Modified files are saved with a .orig suffix before reverting.
4658 To disable these backups, use --no-backup.
4660 To disable these backups, use --no-backup.
4659
4661
4660 See :hg:`help dates` for a list of formats valid for -d/--date.
4662 See :hg:`help dates` for a list of formats valid for -d/--date.
4661
4663
4662 Returns 0 on success.
4664 Returns 0 on success.
4663 """
4665 """
4664
4666
4665 if opts.get("date"):
4667 if opts.get("date"):
4666 if opts.get("rev"):
4668 if opts.get("rev"):
4667 raise util.Abort(_("you can't specify a revision and a date"))
4669 raise util.Abort(_("you can't specify a revision and a date"))
4668 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4670 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4669
4671
4670 parent, p2 = repo.dirstate.parents()
4672 parent, p2 = repo.dirstate.parents()
4671 if not opts.get('rev') and p2 != nullid:
4673 if not opts.get('rev') and p2 != nullid:
4672 # revert after merge is a trap for new users (issue2915)
4674 # revert after merge is a trap for new users (issue2915)
4673 raise util.Abort(_('uncommitted merge with no revision specified'),
4675 raise util.Abort(_('uncommitted merge with no revision specified'),
4674 hint=_('use "hg update" or see "hg help revert"'))
4676 hint=_('use "hg update" or see "hg help revert"'))
4675
4677
4676 ctx = scmutil.revsingle(repo, opts.get('rev'))
4678 ctx = scmutil.revsingle(repo, opts.get('rev'))
4677 node = ctx.node()
4679 node = ctx.node()
4678
4680
4679 if not pats and not opts.get('all'):
4681 if not pats and not opts.get('all'):
4680 msg = _("no files or directories specified")
4682 msg = _("no files or directories specified")
4681 if p2 != nullid:
4683 if p2 != nullid:
4682 hint = _("uncommitted merge, use --all to discard all changes,"
4684 hint = _("uncommitted merge, use --all to discard all changes,"
4683 " or 'hg update -C .' to abort the merge")
4685 " or 'hg update -C .' to abort the merge")
4684 raise util.Abort(msg, hint=hint)
4686 raise util.Abort(msg, hint=hint)
4685 dirty = util.any(repo.status())
4687 dirty = util.any(repo.status())
4686 if node != parent:
4688 if node != parent:
4687 if dirty:
4689 if dirty:
4688 hint = _("uncommitted changes, use --all to discard all"
4690 hint = _("uncommitted changes, use --all to discard all"
4689 " changes, or 'hg update %s' to update") % ctx.rev()
4691 " changes, or 'hg update %s' to update") % ctx.rev()
4690 else:
4692 else:
4691 hint = _("use --all to revert all files,"
4693 hint = _("use --all to revert all files,"
4692 " or 'hg update %s' to update") % ctx.rev()
4694 " or 'hg update %s' to update") % ctx.rev()
4693 elif dirty:
4695 elif dirty:
4694 hint = _("uncommitted changes, use --all to discard all changes")
4696 hint = _("uncommitted changes, use --all to discard all changes")
4695 else:
4697 else:
4696 hint = _("use --all to revert all files")
4698 hint = _("use --all to revert all files")
4697 raise util.Abort(msg, hint=hint)
4699 raise util.Abort(msg, hint=hint)
4698
4700
4699 mf = ctx.manifest()
4701 mf = ctx.manifest()
4700 if node == parent:
4702 if node == parent:
4701 pmf = mf
4703 pmf = mf
4702 else:
4704 else:
4703 pmf = None
4705 pmf = None
4704
4706
4705 # need all matching names in dirstate and manifest of target rev,
4707 # need all matching names in dirstate and manifest of target rev,
4706 # so have to walk both. do not print errors if files exist in one
4708 # so have to walk both. do not print errors if files exist in one
4707 # but not other.
4709 # but not other.
4708
4710
4709 names = {}
4711 names = {}
4710
4712
4711 wlock = repo.wlock()
4713 wlock = repo.wlock()
4712 try:
4714 try:
4713 # walk dirstate.
4715 # walk dirstate.
4714
4716
4715 m = scmutil.match(repo[None], pats, opts)
4717 m = scmutil.match(repo[None], pats, opts)
4716 m.bad = lambda x, y: False
4718 m.bad = lambda x, y: False
4717 for abs in repo.walk(m):
4719 for abs in repo.walk(m):
4718 names[abs] = m.rel(abs), m.exact(abs)
4720 names[abs] = m.rel(abs), m.exact(abs)
4719
4721
4720 # walk target manifest.
4722 # walk target manifest.
4721
4723
4722 def badfn(path, msg):
4724 def badfn(path, msg):
4723 if path in names:
4725 if path in names:
4724 return
4726 return
4725 if path in repo[node].substate:
4727 if path in repo[node].substate:
4726 ui.warn("%s: %s\n" % (m.rel(path),
4728 ui.warn("%s: %s\n" % (m.rel(path),
4727 'reverting subrepos is unsupported'))
4729 'reverting subrepos is unsupported'))
4728 return
4730 return
4729 path_ = path + '/'
4731 path_ = path + '/'
4730 for f in names:
4732 for f in names:
4731 if f.startswith(path_):
4733 if f.startswith(path_):
4732 return
4734 return
4733 ui.warn("%s: %s\n" % (m.rel(path), msg))
4735 ui.warn("%s: %s\n" % (m.rel(path), msg))
4734
4736
4735 m = scmutil.match(repo[node], pats, opts)
4737 m = scmutil.match(repo[node], pats, opts)
4736 m.bad = badfn
4738 m.bad = badfn
4737 for abs in repo[node].walk(m):
4739 for abs in repo[node].walk(m):
4738 if abs not in names:
4740 if abs not in names:
4739 names[abs] = m.rel(abs), m.exact(abs)
4741 names[abs] = m.rel(abs), m.exact(abs)
4740
4742
4741 m = scmutil.matchfiles(repo, names)
4743 m = scmutil.matchfiles(repo, names)
4742 changes = repo.status(match=m)[:4]
4744 changes = repo.status(match=m)[:4]
4743 modified, added, removed, deleted = map(set, changes)
4745 modified, added, removed, deleted = map(set, changes)
4744
4746
4745 # if f is a rename, also revert the source
4747 # if f is a rename, also revert the source
4746 cwd = repo.getcwd()
4748 cwd = repo.getcwd()
4747 for f in added:
4749 for f in added:
4748 src = repo.dirstate.copied(f)
4750 src = repo.dirstate.copied(f)
4749 if src and src not in names and repo.dirstate[src] == 'r':
4751 if src and src not in names and repo.dirstate[src] == 'r':
4750 removed.add(src)
4752 removed.add(src)
4751 names[src] = (repo.pathto(src, cwd), True)
4753 names[src] = (repo.pathto(src, cwd), True)
4752
4754
4753 def removeforget(abs):
4755 def removeforget(abs):
4754 if repo.dirstate[abs] == 'a':
4756 if repo.dirstate[abs] == 'a':
4755 return _('forgetting %s\n')
4757 return _('forgetting %s\n')
4756 return _('removing %s\n')
4758 return _('removing %s\n')
4757
4759
4758 revert = ([], _('reverting %s\n'))
4760 revert = ([], _('reverting %s\n'))
4759 add = ([], _('adding %s\n'))
4761 add = ([], _('adding %s\n'))
4760 remove = ([], removeforget)
4762 remove = ([], removeforget)
4761 undelete = ([], _('undeleting %s\n'))
4763 undelete = ([], _('undeleting %s\n'))
4762
4764
4763 disptable = (
4765 disptable = (
4764 # dispatch table:
4766 # dispatch table:
4765 # file state
4767 # file state
4766 # action if in target manifest
4768 # action if in target manifest
4767 # action if not in target manifest
4769 # action if not in target manifest
4768 # make backup if in target manifest
4770 # make backup if in target manifest
4769 # make backup if not in target manifest
4771 # make backup if not in target manifest
4770 (modified, revert, remove, True, True),
4772 (modified, revert, remove, True, True),
4771 (added, revert, remove, True, False),
4773 (added, revert, remove, True, False),
4772 (removed, undelete, None, False, False),
4774 (removed, undelete, None, False, False),
4773 (deleted, revert, remove, False, False),
4775 (deleted, revert, remove, False, False),
4774 )
4776 )
4775
4777
4776 for abs, (rel, exact) in sorted(names.items()):
4778 for abs, (rel, exact) in sorted(names.items()):
4777 mfentry = mf.get(abs)
4779 mfentry = mf.get(abs)
4778 target = repo.wjoin(abs)
4780 target = repo.wjoin(abs)
4779 def handle(xlist, dobackup):
4781 def handle(xlist, dobackup):
4780 xlist[0].append(abs)
4782 xlist[0].append(abs)
4781 if (dobackup and not opts.get('no_backup') and
4783 if (dobackup and not opts.get('no_backup') and
4782 os.path.lexists(target)):
4784 os.path.lexists(target)):
4783 bakname = "%s.orig" % rel
4785 bakname = "%s.orig" % rel
4784 ui.note(_('saving current version of %s as %s\n') %
4786 ui.note(_('saving current version of %s as %s\n') %
4785 (rel, bakname))
4787 (rel, bakname))
4786 if not opts.get('dry_run'):
4788 if not opts.get('dry_run'):
4787 util.rename(target, bakname)
4789 util.rename(target, bakname)
4788 if ui.verbose or not exact:
4790 if ui.verbose or not exact:
4789 msg = xlist[1]
4791 msg = xlist[1]
4790 if not isinstance(msg, basestring):
4792 if not isinstance(msg, basestring):
4791 msg = msg(abs)
4793 msg = msg(abs)
4792 ui.status(msg % rel)
4794 ui.status(msg % rel)
4793 for table, hitlist, misslist, backuphit, backupmiss in disptable:
4795 for table, hitlist, misslist, backuphit, backupmiss in disptable:
4794 if abs not in table:
4796 if abs not in table:
4795 continue
4797 continue
4796 # file has changed in dirstate
4798 # file has changed in dirstate
4797 if mfentry:
4799 if mfentry:
4798 handle(hitlist, backuphit)
4800 handle(hitlist, backuphit)
4799 elif misslist is not None:
4801 elif misslist is not None:
4800 handle(misslist, backupmiss)
4802 handle(misslist, backupmiss)
4801 break
4803 break
4802 else:
4804 else:
4803 if abs not in repo.dirstate:
4805 if abs not in repo.dirstate:
4804 if mfentry:
4806 if mfentry:
4805 handle(add, True)
4807 handle(add, True)
4806 elif exact:
4808 elif exact:
4807 ui.warn(_('file not managed: %s\n') % rel)
4809 ui.warn(_('file not managed: %s\n') % rel)
4808 continue
4810 continue
4809 # file has not changed in dirstate
4811 # file has not changed in dirstate
4810 if node == parent:
4812 if node == parent:
4811 if exact:
4813 if exact:
4812 ui.warn(_('no changes needed to %s\n') % rel)
4814 ui.warn(_('no changes needed to %s\n') % rel)
4813 continue
4815 continue
4814 if pmf is None:
4816 if pmf is None:
4815 # only need parent manifest in this unlikely case,
4817 # only need parent manifest in this unlikely case,
4816 # so do not read by default
4818 # so do not read by default
4817 pmf = repo[parent].manifest()
4819 pmf = repo[parent].manifest()
4818 if abs in pmf and mfentry:
4820 if abs in pmf and mfentry:
4819 # if version of file is same in parent and target
4821 # if version of file is same in parent and target
4820 # manifests, do nothing
4822 # manifests, do nothing
4821 if (pmf[abs] != mfentry or
4823 if (pmf[abs] != mfentry or
4822 pmf.flags(abs) != mf.flags(abs)):
4824 pmf.flags(abs) != mf.flags(abs)):
4823 handle(revert, False)
4825 handle(revert, False)
4824 else:
4826 else:
4825 handle(remove, False)
4827 handle(remove, False)
4826
4828
4827 if not opts.get('dry_run'):
4829 if not opts.get('dry_run'):
4828 def checkout(f):
4830 def checkout(f):
4829 fc = ctx[f]
4831 fc = ctx[f]
4830 repo.wwrite(f, fc.data(), fc.flags())
4832 repo.wwrite(f, fc.data(), fc.flags())
4831
4833
4832 audit_path = scmutil.pathauditor(repo.root)
4834 audit_path = scmutil.pathauditor(repo.root)
4833 for f in remove[0]:
4835 for f in remove[0]:
4834 if repo.dirstate[f] == 'a':
4836 if repo.dirstate[f] == 'a':
4835 repo.dirstate.drop(f)
4837 repo.dirstate.drop(f)
4836 continue
4838 continue
4837 audit_path(f)
4839 audit_path(f)
4838 try:
4840 try:
4839 util.unlinkpath(repo.wjoin(f))
4841 util.unlinkpath(repo.wjoin(f))
4840 except OSError:
4842 except OSError:
4841 pass
4843 pass
4842 repo.dirstate.remove(f)
4844 repo.dirstate.remove(f)
4843
4845
4844 normal = None
4846 normal = None
4845 if node == parent:
4847 if node == parent:
4846 # We're reverting to our parent. If possible, we'd like status
4848 # We're reverting to our parent. If possible, we'd like status
4847 # to report the file as clean. We have to use normallookup for
4849 # to report the file as clean. We have to use normallookup for
4848 # merges to avoid losing information about merged/dirty files.
4850 # merges to avoid losing information about merged/dirty files.
4849 if p2 != nullid:
4851 if p2 != nullid:
4850 normal = repo.dirstate.normallookup
4852 normal = repo.dirstate.normallookup
4851 else:
4853 else:
4852 normal = repo.dirstate.normal
4854 normal = repo.dirstate.normal
4853 for f in revert[0]:
4855 for f in revert[0]:
4854 checkout(f)
4856 checkout(f)
4855 if normal:
4857 if normal:
4856 normal(f)
4858 normal(f)
4857
4859
4858 for f in add[0]:
4860 for f in add[0]:
4859 checkout(f)
4861 checkout(f)
4860 repo.dirstate.add(f)
4862 repo.dirstate.add(f)
4861
4863
4862 normal = repo.dirstate.normallookup
4864 normal = repo.dirstate.normallookup
4863 if node == parent and p2 == nullid:
4865 if node == parent and p2 == nullid:
4864 normal = repo.dirstate.normal
4866 normal = repo.dirstate.normal
4865 for f in undelete[0]:
4867 for f in undelete[0]:
4866 checkout(f)
4868 checkout(f)
4867 normal(f)
4869 normal(f)
4868
4870
4869 finally:
4871 finally:
4870 wlock.release()
4872 wlock.release()
4871
4873
4872 @command('rollback', dryrunopts +
4874 @command('rollback', dryrunopts +
4873 [('f', 'force', False, _('ignore safety measures'))])
4875 [('f', 'force', False, _('ignore safety measures'))])
4874 def rollback(ui, repo, **opts):
4876 def rollback(ui, repo, **opts):
4875 """roll back the last transaction (dangerous)
4877 """roll back the last transaction (dangerous)
4876
4878
4877 This command should be used with care. There is only one level of
4879 This command should be used with care. There is only one level of
4878 rollback, and there is no way to undo a rollback. It will also
4880 rollback, and there is no way to undo a rollback. It will also
4879 restore the dirstate at the time of the last transaction, losing
4881 restore the dirstate at the time of the last transaction, losing
4880 any dirstate changes since that time. This command does not alter
4882 any dirstate changes since that time. This command does not alter
4881 the working directory.
4883 the working directory.
4882
4884
4883 Transactions are used to encapsulate the effects of all commands
4885 Transactions are used to encapsulate the effects of all commands
4884 that create new changesets or propagate existing changesets into a
4886 that create new changesets or propagate existing changesets into a
4885 repository. For example, the following commands are transactional,
4887 repository. For example, the following commands are transactional,
4886 and their effects can be rolled back:
4888 and their effects can be rolled back:
4887
4889
4888 - commit
4890 - commit
4889 - import
4891 - import
4890 - pull
4892 - pull
4891 - push (with this repository as the destination)
4893 - push (with this repository as the destination)
4892 - unbundle
4894 - unbundle
4893
4895
4894 It's possible to lose data with rollback: commit, update back to
4896 It's possible to lose data with rollback: commit, update back to
4895 an older changeset, and then rollback. The update removes the
4897 an older changeset, and then rollback. The update removes the
4896 changes you committed from the working directory, and rollback
4898 changes you committed from the working directory, and rollback
4897 removes them from history. To avoid data loss, you must pass
4899 removes them from history. To avoid data loss, you must pass
4898 --force in this case.
4900 --force in this case.
4899
4901
4900 This command is not intended for use on public repositories. Once
4902 This command is not intended for use on public repositories. Once
4901 changes are visible for pull by other users, rolling a transaction
4903 changes are visible for pull by other users, rolling a transaction
4902 back locally is ineffective (someone else may already have pulled
4904 back locally is ineffective (someone else may already have pulled
4903 the changes). Furthermore, a race is possible with readers of the
4905 the changes). Furthermore, a race is possible with readers of the
4904 repository; for example an in-progress pull from the repository
4906 repository; for example an in-progress pull from the repository
4905 may fail if a rollback is performed.
4907 may fail if a rollback is performed.
4906
4908
4907 Returns 0 on success, 1 if no rollback data is available.
4909 Returns 0 on success, 1 if no rollback data is available.
4908 """
4910 """
4909 return repo.rollback(dryrun=opts.get('dry_run'),
4911 return repo.rollback(dryrun=opts.get('dry_run'),
4910 force=opts.get('force'))
4912 force=opts.get('force'))
4911
4913
4912 @command('root', [])
4914 @command('root', [])
4913 def root(ui, repo):
4915 def root(ui, repo):
4914 """print the root (top) of the current working directory
4916 """print the root (top) of the current working directory
4915
4917
4916 Print the root directory of the current repository.
4918 Print the root directory of the current repository.
4917
4919
4918 Returns 0 on success.
4920 Returns 0 on success.
4919 """
4921 """
4920 ui.write(repo.root + "\n")
4922 ui.write(repo.root + "\n")
4921
4923
4922 @command('^serve',
4924 @command('^serve',
4923 [('A', 'accesslog', '', _('name of access log file to write to'),
4925 [('A', 'accesslog', '', _('name of access log file to write to'),
4924 _('FILE')),
4926 _('FILE')),
4925 ('d', 'daemon', None, _('run server in background')),
4927 ('d', 'daemon', None, _('run server in background')),
4926 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
4928 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
4927 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4929 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4928 # use string type, then we can check if something was passed
4930 # use string type, then we can check if something was passed
4929 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4931 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4930 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4932 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4931 _('ADDR')),
4933 _('ADDR')),
4932 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4934 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4933 _('PREFIX')),
4935 _('PREFIX')),
4934 ('n', 'name', '',
4936 ('n', 'name', '',
4935 _('name to show in web pages (default: working directory)'), _('NAME')),
4937 _('name to show in web pages (default: working directory)'), _('NAME')),
4936 ('', 'web-conf', '',
4938 ('', 'web-conf', '',
4937 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
4939 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
4938 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4940 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4939 _('FILE')),
4941 _('FILE')),
4940 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4942 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4941 ('', 'stdio', None, _('for remote clients')),
4943 ('', 'stdio', None, _('for remote clients')),
4942 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
4944 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
4943 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4945 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4944 ('', 'style', '', _('template style to use'), _('STYLE')),
4946 ('', 'style', '', _('template style to use'), _('STYLE')),
4945 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4947 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4946 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4948 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4947 _('[OPTION]...'))
4949 _('[OPTION]...'))
4948 def serve(ui, repo, **opts):
4950 def serve(ui, repo, **opts):
4949 """start stand-alone webserver
4951 """start stand-alone webserver
4950
4952
4951 Start a local HTTP repository browser and pull server. You can use
4953 Start a local HTTP repository browser and pull server. You can use
4952 this for ad-hoc sharing and browsing of repositories. It is
4954 this for ad-hoc sharing and browsing of repositories. It is
4953 recommended to use a real web server to serve a repository for
4955 recommended to use a real web server to serve a repository for
4954 longer periods of time.
4956 longer periods of time.
4955
4957
4956 Please note that the server does not implement access control.
4958 Please note that the server does not implement access control.
4957 This means that, by default, anybody can read from the server and
4959 This means that, by default, anybody can read from the server and
4958 nobody can write to it by default. Set the ``web.allow_push``
4960 nobody can write to it by default. Set the ``web.allow_push``
4959 option to ``*`` to allow everybody to push to the server. You
4961 option to ``*`` to allow everybody to push to the server. You
4960 should use a real web server if you need to authenticate users.
4962 should use a real web server if you need to authenticate users.
4961
4963
4962 By default, the server logs accesses to stdout and errors to
4964 By default, the server logs accesses to stdout and errors to
4963 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4965 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4964 files.
4966 files.
4965
4967
4966 To have the server choose a free port number to listen on, specify
4968 To have the server choose a free port number to listen on, specify
4967 a port number of 0; in this case, the server will print the port
4969 a port number of 0; in this case, the server will print the port
4968 number it uses.
4970 number it uses.
4969
4971
4970 Returns 0 on success.
4972 Returns 0 on success.
4971 """
4973 """
4972
4974
4973 if opts["stdio"] and opts["cmdserver"]:
4975 if opts["stdio"] and opts["cmdserver"]:
4974 raise util.Abort(_("cannot use --stdio with --cmdserver"))
4976 raise util.Abort(_("cannot use --stdio with --cmdserver"))
4975
4977
4976 def checkrepo():
4978 def checkrepo():
4977 if repo is None:
4979 if repo is None:
4978 raise error.RepoError(_("There is no Mercurial repository here"
4980 raise error.RepoError(_("There is no Mercurial repository here"
4979 " (.hg not found)"))
4981 " (.hg not found)"))
4980
4982
4981 if opts["stdio"]:
4983 if opts["stdio"]:
4982 checkrepo()
4984 checkrepo()
4983 s = sshserver.sshserver(ui, repo)
4985 s = sshserver.sshserver(ui, repo)
4984 s.serve_forever()
4986 s.serve_forever()
4985
4987
4986 if opts["cmdserver"]:
4988 if opts["cmdserver"]:
4987 checkrepo()
4989 checkrepo()
4988 s = commandserver.server(ui, repo, opts["cmdserver"])
4990 s = commandserver.server(ui, repo, opts["cmdserver"])
4989 return s.serve()
4991 return s.serve()
4990
4992
4991 # this way we can check if something was given in the command-line
4993 # this way we can check if something was given in the command-line
4992 if opts.get('port'):
4994 if opts.get('port'):
4993 opts['port'] = util.getport(opts.get('port'))
4995 opts['port'] = util.getport(opts.get('port'))
4994
4996
4995 baseui = repo and repo.baseui or ui
4997 baseui = repo and repo.baseui or ui
4996 optlist = ("name templates style address port prefix ipv6"
4998 optlist = ("name templates style address port prefix ipv6"
4997 " accesslog errorlog certificate encoding")
4999 " accesslog errorlog certificate encoding")
4998 for o in optlist.split():
5000 for o in optlist.split():
4999 val = opts.get(o, '')
5001 val = opts.get(o, '')
5000 if val in (None, ''): # should check against default options instead
5002 if val in (None, ''): # should check against default options instead
5001 continue
5003 continue
5002 baseui.setconfig("web", o, val)
5004 baseui.setconfig("web", o, val)
5003 if repo and repo.ui != baseui:
5005 if repo and repo.ui != baseui:
5004 repo.ui.setconfig("web", o, val)
5006 repo.ui.setconfig("web", o, val)
5005
5007
5006 o = opts.get('web_conf') or opts.get('webdir_conf')
5008 o = opts.get('web_conf') or opts.get('webdir_conf')
5007 if not o:
5009 if not o:
5008 if not repo:
5010 if not repo:
5009 raise error.RepoError(_("There is no Mercurial repository"
5011 raise error.RepoError(_("There is no Mercurial repository"
5010 " here (.hg not found)"))
5012 " here (.hg not found)"))
5011 o = repo.root
5013 o = repo.root
5012
5014
5013 app = hgweb.hgweb(o, baseui=ui)
5015 app = hgweb.hgweb(o, baseui=ui)
5014
5016
5015 class service(object):
5017 class service(object):
5016 def init(self):
5018 def init(self):
5017 util.setsignalhandler()
5019 util.setsignalhandler()
5018 self.httpd = hgweb.server.create_server(ui, app)
5020 self.httpd = hgweb.server.create_server(ui, app)
5019
5021
5020 if opts['port'] and not ui.verbose:
5022 if opts['port'] and not ui.verbose:
5021 return
5023 return
5022
5024
5023 if self.httpd.prefix:
5025 if self.httpd.prefix:
5024 prefix = self.httpd.prefix.strip('/') + '/'
5026 prefix = self.httpd.prefix.strip('/') + '/'
5025 else:
5027 else:
5026 prefix = ''
5028 prefix = ''
5027
5029
5028 port = ':%d' % self.httpd.port
5030 port = ':%d' % self.httpd.port
5029 if port == ':80':
5031 if port == ':80':
5030 port = ''
5032 port = ''
5031
5033
5032 bindaddr = self.httpd.addr
5034 bindaddr = self.httpd.addr
5033 if bindaddr == '0.0.0.0':
5035 if bindaddr == '0.0.0.0':
5034 bindaddr = '*'
5036 bindaddr = '*'
5035 elif ':' in bindaddr: # IPv6
5037 elif ':' in bindaddr: # IPv6
5036 bindaddr = '[%s]' % bindaddr
5038 bindaddr = '[%s]' % bindaddr
5037
5039
5038 fqaddr = self.httpd.fqaddr
5040 fqaddr = self.httpd.fqaddr
5039 if ':' in fqaddr:
5041 if ':' in fqaddr:
5040 fqaddr = '[%s]' % fqaddr
5042 fqaddr = '[%s]' % fqaddr
5041 if opts['port']:
5043 if opts['port']:
5042 write = ui.status
5044 write = ui.status
5043 else:
5045 else:
5044 write = ui.write
5046 write = ui.write
5045 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5047 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5046 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5048 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5047
5049
5048 def run(self):
5050 def run(self):
5049 self.httpd.serve_forever()
5051 self.httpd.serve_forever()
5050
5052
5051 service = service()
5053 service = service()
5052
5054
5053 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5055 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5054
5056
5055 @command('showconfig|debugconfig',
5057 @command('showconfig|debugconfig',
5056 [('u', 'untrusted', None, _('show untrusted configuration options'))],
5058 [('u', 'untrusted', None, _('show untrusted configuration options'))],
5057 _('[-u] [NAME]...'))
5059 _('[-u] [NAME]...'))
5058 def showconfig(ui, repo, *values, **opts):
5060 def showconfig(ui, repo, *values, **opts):
5059 """show combined config settings from all hgrc files
5061 """show combined config settings from all hgrc files
5060
5062
5061 With no arguments, print names and values of all config items.
5063 With no arguments, print names and values of all config items.
5062
5064
5063 With one argument of the form section.name, print just the value
5065 With one argument of the form section.name, print just the value
5064 of that config item.
5066 of that config item.
5065
5067
5066 With multiple arguments, print names and values of all config
5068 With multiple arguments, print names and values of all config
5067 items with matching section names.
5069 items with matching section names.
5068
5070
5069 With --debug, the source (filename and line number) is printed
5071 With --debug, the source (filename and line number) is printed
5070 for each config item.
5072 for each config item.
5071
5073
5072 Returns 0 on success.
5074 Returns 0 on success.
5073 """
5075 """
5074
5076
5075 for f in scmutil.rcpath():
5077 for f in scmutil.rcpath():
5076 ui.debug('read config from: %s\n' % f)
5078 ui.debug('read config from: %s\n' % f)
5077 untrusted = bool(opts.get('untrusted'))
5079 untrusted = bool(opts.get('untrusted'))
5078 if values:
5080 if values:
5079 sections = [v for v in values if '.' not in v]
5081 sections = [v for v in values if '.' not in v]
5080 items = [v for v in values if '.' in v]
5082 items = [v for v in values if '.' in v]
5081 if len(items) > 1 or items and sections:
5083 if len(items) > 1 or items and sections:
5082 raise util.Abort(_('only one config item permitted'))
5084 raise util.Abort(_('only one config item permitted'))
5083 for section, name, value in ui.walkconfig(untrusted=untrusted):
5085 for section, name, value in ui.walkconfig(untrusted=untrusted):
5084 value = str(value).replace('\n', '\\n')
5086 value = str(value).replace('\n', '\\n')
5085 sectname = section + '.' + name
5087 sectname = section + '.' + name
5086 if values:
5088 if values:
5087 for v in values:
5089 for v in values:
5088 if v == section:
5090 if v == section:
5089 ui.debug('%s: ' %
5091 ui.debug('%s: ' %
5090 ui.configsource(section, name, untrusted))
5092 ui.configsource(section, name, untrusted))
5091 ui.write('%s=%s\n' % (sectname, value))
5093 ui.write('%s=%s\n' % (sectname, value))
5092 elif v == sectname:
5094 elif v == sectname:
5093 ui.debug('%s: ' %
5095 ui.debug('%s: ' %
5094 ui.configsource(section, name, untrusted))
5096 ui.configsource(section, name, untrusted))
5095 ui.write(value, '\n')
5097 ui.write(value, '\n')
5096 else:
5098 else:
5097 ui.debug('%s: ' %
5099 ui.debug('%s: ' %
5098 ui.configsource(section, name, untrusted))
5100 ui.configsource(section, name, untrusted))
5099 ui.write('%s=%s\n' % (sectname, value))
5101 ui.write('%s=%s\n' % (sectname, value))
5100
5102
5101 @command('^status|st',
5103 @command('^status|st',
5102 [('A', 'all', None, _('show status of all files')),
5104 [('A', 'all', None, _('show status of all files')),
5103 ('m', 'modified', None, _('show only modified files')),
5105 ('m', 'modified', None, _('show only modified files')),
5104 ('a', 'added', None, _('show only added files')),
5106 ('a', 'added', None, _('show only added files')),
5105 ('r', 'removed', None, _('show only removed files')),
5107 ('r', 'removed', None, _('show only removed files')),
5106 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5108 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5107 ('c', 'clean', None, _('show only files without changes')),
5109 ('c', 'clean', None, _('show only files without changes')),
5108 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5110 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5109 ('i', 'ignored', None, _('show only ignored files')),
5111 ('i', 'ignored', None, _('show only ignored files')),
5110 ('n', 'no-status', None, _('hide status prefix')),
5112 ('n', 'no-status', None, _('hide status prefix')),
5111 ('C', 'copies', None, _('show source of copied files')),
5113 ('C', 'copies', None, _('show source of copied files')),
5112 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5114 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5113 ('', 'rev', [], _('show difference from revision'), _('REV')),
5115 ('', 'rev', [], _('show difference from revision'), _('REV')),
5114 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5116 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5115 ] + walkopts + subrepoopts,
5117 ] + walkopts + subrepoopts,
5116 _('[OPTION]... [FILE]...'))
5118 _('[OPTION]... [FILE]...'))
5117 def status(ui, repo, *pats, **opts):
5119 def status(ui, repo, *pats, **opts):
5118 """show changed files in the working directory
5120 """show changed files in the working directory
5119
5121
5120 Show status of files in the repository. If names are given, only
5122 Show status of files in the repository. If names are given, only
5121 files that match are shown. Files that are clean or ignored or
5123 files that match are shown. Files that are clean or ignored or
5122 the source of a copy/move operation, are not listed unless
5124 the source of a copy/move operation, are not listed unless
5123 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5125 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5124 Unless options described with "show only ..." are given, the
5126 Unless options described with "show only ..." are given, the
5125 options -mardu are used.
5127 options -mardu are used.
5126
5128
5127 Option -q/--quiet hides untracked (unknown and ignored) files
5129 Option -q/--quiet hides untracked (unknown and ignored) files
5128 unless explicitly requested with -u/--unknown or -i/--ignored.
5130 unless explicitly requested with -u/--unknown or -i/--ignored.
5129
5131
5130 .. note::
5132 .. note::
5131 status may appear to disagree with diff if permissions have
5133 status may appear to disagree with diff if permissions have
5132 changed or a merge has occurred. The standard diff format does
5134 changed or a merge has occurred. The standard diff format does
5133 not report permission changes and diff only reports changes
5135 not report permission changes and diff only reports changes
5134 relative to one merge parent.
5136 relative to one merge parent.
5135
5137
5136 If one revision is given, it is used as the base revision.
5138 If one revision is given, it is used as the base revision.
5137 If two revisions are given, the differences between them are
5139 If two revisions are given, the differences between them are
5138 shown. The --change option can also be used as a shortcut to list
5140 shown. The --change option can also be used as a shortcut to list
5139 the changed files of a revision from its first parent.
5141 the changed files of a revision from its first parent.
5140
5142
5141 The codes used to show the status of files are::
5143 The codes used to show the status of files are::
5142
5144
5143 M = modified
5145 M = modified
5144 A = added
5146 A = added
5145 R = removed
5147 R = removed
5146 C = clean
5148 C = clean
5147 ! = missing (deleted by non-hg command, but still tracked)
5149 ! = missing (deleted by non-hg command, but still tracked)
5148 ? = not tracked
5150 ? = not tracked
5149 I = ignored
5151 I = ignored
5150 = origin of the previous file listed as A (added)
5152 = origin of the previous file listed as A (added)
5151
5153
5152 .. container:: verbose
5154 .. container:: verbose
5153
5155
5154 Examples:
5156 Examples:
5155
5157
5156 - show changes in the working directory relative to a changeset:
5158 - show changes in the working directory relative to a changeset:
5157
5159
5158 hg status --rev 9353
5160 hg status --rev 9353
5159
5161
5160 - show all changes including copies in an existing changeset::
5162 - show all changes including copies in an existing changeset::
5161
5163
5162 hg status --copies --change 9353
5164 hg status --copies --change 9353
5163
5165
5164 - get a NUL separated list of added files, suitable for xargs::
5166 - get a NUL separated list of added files, suitable for xargs::
5165
5167
5166 hg status -an0
5168 hg status -an0
5167
5169
5168 Returns 0 on success.
5170 Returns 0 on success.
5169 """
5171 """
5170
5172
5171 revs = opts.get('rev')
5173 revs = opts.get('rev')
5172 change = opts.get('change')
5174 change = opts.get('change')
5173
5175
5174 if revs and change:
5176 if revs and change:
5175 msg = _('cannot specify --rev and --change at the same time')
5177 msg = _('cannot specify --rev and --change at the same time')
5176 raise util.Abort(msg)
5178 raise util.Abort(msg)
5177 elif change:
5179 elif change:
5178 node2 = scmutil.revsingle(repo, change, None).node()
5180 node2 = scmutil.revsingle(repo, change, None).node()
5179 node1 = repo[node2].p1().node()
5181 node1 = repo[node2].p1().node()
5180 else:
5182 else:
5181 node1, node2 = scmutil.revpair(repo, revs)
5183 node1, node2 = scmutil.revpair(repo, revs)
5182
5184
5183 cwd = (pats and repo.getcwd()) or ''
5185 cwd = (pats and repo.getcwd()) or ''
5184 end = opts.get('print0') and '\0' or '\n'
5186 end = opts.get('print0') and '\0' or '\n'
5185 copy = {}
5187 copy = {}
5186 states = 'modified added removed deleted unknown ignored clean'.split()
5188 states = 'modified added removed deleted unknown ignored clean'.split()
5187 show = [k for k in states if opts.get(k)]
5189 show = [k for k in states if opts.get(k)]
5188 if opts.get('all'):
5190 if opts.get('all'):
5189 show += ui.quiet and (states[:4] + ['clean']) or states
5191 show += ui.quiet and (states[:4] + ['clean']) or states
5190 if not show:
5192 if not show:
5191 show = ui.quiet and states[:4] or states[:5]
5193 show = ui.quiet and states[:4] or states[:5]
5192
5194
5193 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5195 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5194 'ignored' in show, 'clean' in show, 'unknown' in show,
5196 'ignored' in show, 'clean' in show, 'unknown' in show,
5195 opts.get('subrepos'))
5197 opts.get('subrepos'))
5196 changestates = zip(states, 'MAR!?IC', stat)
5198 changestates = zip(states, 'MAR!?IC', stat)
5197
5199
5198 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5200 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5199 ctxn = repo[nullid]
5201 ctxn = repo[nullid]
5200 ctx1 = repo[node1]
5202 ctx1 = repo[node1]
5201 ctx2 = repo[node2]
5203 ctx2 = repo[node2]
5202 added = stat[1]
5204 added = stat[1]
5203 if node2 is None:
5205 if node2 is None:
5204 added = stat[0] + stat[1] # merged?
5206 added = stat[0] + stat[1] # merged?
5205
5207
5206 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
5208 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
5207 if k in added:
5209 if k in added:
5208 copy[k] = v
5210 copy[k] = v
5209 elif v in added:
5211 elif v in added:
5210 copy[v] = k
5212 copy[v] = k
5211
5213
5212 for state, char, files in changestates:
5214 for state, char, files in changestates:
5213 if state in show:
5215 if state in show:
5214 format = "%s %%s%s" % (char, end)
5216 format = "%s %%s%s" % (char, end)
5215 if opts.get('no_status'):
5217 if opts.get('no_status'):
5216 format = "%%s%s" % end
5218 format = "%%s%s" % end
5217
5219
5218 for f in files:
5220 for f in files:
5219 ui.write(format % repo.pathto(f, cwd),
5221 ui.write(format % repo.pathto(f, cwd),
5220 label='status.' + state)
5222 label='status.' + state)
5221 if f in copy:
5223 if f in copy:
5222 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
5224 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
5223 label='status.copied')
5225 label='status.copied')
5224
5226
5225 @command('^summary|sum',
5227 @command('^summary|sum',
5226 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5228 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5227 def summary(ui, repo, **opts):
5229 def summary(ui, repo, **opts):
5228 """summarize working directory state
5230 """summarize working directory state
5229
5231
5230 This generates a brief summary of the working directory state,
5232 This generates a brief summary of the working directory state,
5231 including parents, branch, commit status, and available updates.
5233 including parents, branch, commit status, and available updates.
5232
5234
5233 With the --remote option, this will check the default paths for
5235 With the --remote option, this will check the default paths for
5234 incoming and outgoing changes. This can be time-consuming.
5236 incoming and outgoing changes. This can be time-consuming.
5235
5237
5236 Returns 0 on success.
5238 Returns 0 on success.
5237 """
5239 """
5238
5240
5239 ctx = repo[None]
5241 ctx = repo[None]
5240 parents = ctx.parents()
5242 parents = ctx.parents()
5241 pnode = parents[0].node()
5243 pnode = parents[0].node()
5242 marks = []
5244 marks = []
5243
5245
5244 for p in parents:
5246 for p in parents:
5245 # label with log.changeset (instead of log.parent) since this
5247 # label with log.changeset (instead of log.parent) since this
5246 # shows a working directory parent *changeset*:
5248 # shows a working directory parent *changeset*:
5247 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5249 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5248 label='log.changeset')
5250 label='log.changeset')
5249 ui.write(' '.join(p.tags()), label='log.tag')
5251 ui.write(' '.join(p.tags()), label='log.tag')
5250 if p.bookmarks():
5252 if p.bookmarks():
5251 marks.extend(p.bookmarks())
5253 marks.extend(p.bookmarks())
5252 if p.rev() == -1:
5254 if p.rev() == -1:
5253 if not len(repo):
5255 if not len(repo):
5254 ui.write(_(' (empty repository)'))
5256 ui.write(_(' (empty repository)'))
5255 else:
5257 else:
5256 ui.write(_(' (no revision checked out)'))
5258 ui.write(_(' (no revision checked out)'))
5257 ui.write('\n')
5259 ui.write('\n')
5258 if p.description():
5260 if p.description():
5259 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5261 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5260 label='log.summary')
5262 label='log.summary')
5261
5263
5262 branch = ctx.branch()
5264 branch = ctx.branch()
5263 bheads = repo.branchheads(branch)
5265 bheads = repo.branchheads(branch)
5264 m = _('branch: %s\n') % branch
5266 m = _('branch: %s\n') % branch
5265 if branch != 'default':
5267 if branch != 'default':
5266 ui.write(m, label='log.branch')
5268 ui.write(m, label='log.branch')
5267 else:
5269 else:
5268 ui.status(m, label='log.branch')
5270 ui.status(m, label='log.branch')
5269
5271
5270 if marks:
5272 if marks:
5271 current = repo._bookmarkcurrent
5273 current = repo._bookmarkcurrent
5272 ui.write(_('bookmarks:'), label='log.bookmark')
5274 ui.write(_('bookmarks:'), label='log.bookmark')
5273 if current is not None:
5275 if current is not None:
5274 try:
5276 try:
5275 marks.remove(current)
5277 marks.remove(current)
5276 ui.write(' *' + current, label='bookmarks.current')
5278 ui.write(' *' + current, label='bookmarks.current')
5277 except ValueError:
5279 except ValueError:
5278 # current bookmark not in parent ctx marks
5280 # current bookmark not in parent ctx marks
5279 pass
5281 pass
5280 for m in marks:
5282 for m in marks:
5281 ui.write(' ' + m, label='log.bookmark')
5283 ui.write(' ' + m, label='log.bookmark')
5282 ui.write('\n', label='log.bookmark')
5284 ui.write('\n', label='log.bookmark')
5283
5285
5284 st = list(repo.status(unknown=True))[:6]
5286 st = list(repo.status(unknown=True))[:6]
5285
5287
5286 c = repo.dirstate.copies()
5288 c = repo.dirstate.copies()
5287 copied, renamed = [], []
5289 copied, renamed = [], []
5288 for d, s in c.iteritems():
5290 for d, s in c.iteritems():
5289 if s in st[2]:
5291 if s in st[2]:
5290 st[2].remove(s)
5292 st[2].remove(s)
5291 renamed.append(d)
5293 renamed.append(d)
5292 else:
5294 else:
5293 copied.append(d)
5295 copied.append(d)
5294 if d in st[1]:
5296 if d in st[1]:
5295 st[1].remove(d)
5297 st[1].remove(d)
5296 st.insert(3, renamed)
5298 st.insert(3, renamed)
5297 st.insert(4, copied)
5299 st.insert(4, copied)
5298
5300
5299 ms = mergemod.mergestate(repo)
5301 ms = mergemod.mergestate(repo)
5300 st.append([f for f in ms if ms[f] == 'u'])
5302 st.append([f for f in ms if ms[f] == 'u'])
5301
5303
5302 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5304 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5303 st.append(subs)
5305 st.append(subs)
5304
5306
5305 labels = [ui.label(_('%d modified'), 'status.modified'),
5307 labels = [ui.label(_('%d modified'), 'status.modified'),
5306 ui.label(_('%d added'), 'status.added'),
5308 ui.label(_('%d added'), 'status.added'),
5307 ui.label(_('%d removed'), 'status.removed'),
5309 ui.label(_('%d removed'), 'status.removed'),
5308 ui.label(_('%d renamed'), 'status.copied'),
5310 ui.label(_('%d renamed'), 'status.copied'),
5309 ui.label(_('%d copied'), 'status.copied'),
5311 ui.label(_('%d copied'), 'status.copied'),
5310 ui.label(_('%d deleted'), 'status.deleted'),
5312 ui.label(_('%d deleted'), 'status.deleted'),
5311 ui.label(_('%d unknown'), 'status.unknown'),
5313 ui.label(_('%d unknown'), 'status.unknown'),
5312 ui.label(_('%d ignored'), 'status.ignored'),
5314 ui.label(_('%d ignored'), 'status.ignored'),
5313 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5315 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5314 ui.label(_('%d subrepos'), 'status.modified')]
5316 ui.label(_('%d subrepos'), 'status.modified')]
5315 t = []
5317 t = []
5316 for s, l in zip(st, labels):
5318 for s, l in zip(st, labels):
5317 if s:
5319 if s:
5318 t.append(l % len(s))
5320 t.append(l % len(s))
5319
5321
5320 t = ', '.join(t)
5322 t = ', '.join(t)
5321 cleanworkdir = False
5323 cleanworkdir = False
5322
5324
5323 if len(parents) > 1:
5325 if len(parents) > 1:
5324 t += _(' (merge)')
5326 t += _(' (merge)')
5325 elif branch != parents[0].branch():
5327 elif branch != parents[0].branch():
5326 t += _(' (new branch)')
5328 t += _(' (new branch)')
5327 elif (parents[0].extra().get('close') and
5329 elif (parents[0].extra().get('close') and
5328 pnode in repo.branchheads(branch, closed=True)):
5330 pnode in repo.branchheads(branch, closed=True)):
5329 t += _(' (head closed)')
5331 t += _(' (head closed)')
5330 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5332 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5331 t += _(' (clean)')
5333 t += _(' (clean)')
5332 cleanworkdir = True
5334 cleanworkdir = True
5333 elif pnode not in bheads:
5335 elif pnode not in bheads:
5334 t += _(' (new branch head)')
5336 t += _(' (new branch head)')
5335
5337
5336 if cleanworkdir:
5338 if cleanworkdir:
5337 ui.status(_('commit: %s\n') % t.strip())
5339 ui.status(_('commit: %s\n') % t.strip())
5338 else:
5340 else:
5339 ui.write(_('commit: %s\n') % t.strip())
5341 ui.write(_('commit: %s\n') % t.strip())
5340
5342
5341 # all ancestors of branch heads - all ancestors of parent = new csets
5343 # all ancestors of branch heads - all ancestors of parent = new csets
5342 new = [0] * len(repo)
5344 new = [0] * len(repo)
5343 cl = repo.changelog
5345 cl = repo.changelog
5344 for a in [cl.rev(n) for n in bheads]:
5346 for a in [cl.rev(n) for n in bheads]:
5345 new[a] = 1
5347 new[a] = 1
5346 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
5348 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
5347 new[a] = 1
5349 new[a] = 1
5348 for a in [p.rev() for p in parents]:
5350 for a in [p.rev() for p in parents]:
5349 if a >= 0:
5351 if a >= 0:
5350 new[a] = 0
5352 new[a] = 0
5351 for a in cl.ancestors(*[p.rev() for p in parents]):
5353 for a in cl.ancestors(*[p.rev() for p in parents]):
5352 new[a] = 0
5354 new[a] = 0
5353 new = sum(new)
5355 new = sum(new)
5354
5356
5355 if new == 0:
5357 if new == 0:
5356 ui.status(_('update: (current)\n'))
5358 ui.status(_('update: (current)\n'))
5357 elif pnode not in bheads:
5359 elif pnode not in bheads:
5358 ui.write(_('update: %d new changesets (update)\n') % new)
5360 ui.write(_('update: %d new changesets (update)\n') % new)
5359 else:
5361 else:
5360 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5362 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5361 (new, len(bheads)))
5363 (new, len(bheads)))
5362
5364
5363 if opts.get('remote'):
5365 if opts.get('remote'):
5364 t = []
5366 t = []
5365 source, branches = hg.parseurl(ui.expandpath('default'))
5367 source, branches = hg.parseurl(ui.expandpath('default'))
5366 other = hg.peer(repo, {}, source)
5368 other = hg.peer(repo, {}, source)
5367 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
5369 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
5368 ui.debug('comparing with %s\n' % util.hidepassword(source))
5370 ui.debug('comparing with %s\n' % util.hidepassword(source))
5369 repo.ui.pushbuffer()
5371 repo.ui.pushbuffer()
5370 commoninc = discovery.findcommonincoming(repo, other)
5372 commoninc = discovery.findcommonincoming(repo, other)
5371 _common, incoming, _rheads = commoninc
5373 _common, incoming, _rheads = commoninc
5372 repo.ui.popbuffer()
5374 repo.ui.popbuffer()
5373 if incoming:
5375 if incoming:
5374 t.append(_('1 or more incoming'))
5376 t.append(_('1 or more incoming'))
5375
5377
5376 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5378 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5377 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5379 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5378 if source != dest:
5380 if source != dest:
5379 other = hg.peer(repo, {}, dest)
5381 other = hg.peer(repo, {}, dest)
5380 commoninc = None
5382 commoninc = None
5381 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5383 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5382 repo.ui.pushbuffer()
5384 repo.ui.pushbuffer()
5383 common, outheads = discovery.findcommonoutgoing(repo, other,
5385 common, outheads = discovery.findcommonoutgoing(repo, other,
5384 commoninc=commoninc)
5386 commoninc=commoninc)
5385 repo.ui.popbuffer()
5387 repo.ui.popbuffer()
5386 o = repo.changelog.findmissing(common=common, heads=outheads)
5388 o = repo.changelog.findmissing(common=common, heads=outheads)
5387 if o:
5389 if o:
5388 t.append(_('%d outgoing') % len(o))
5390 t.append(_('%d outgoing') % len(o))
5389 if 'bookmarks' in other.listkeys('namespaces'):
5391 if 'bookmarks' in other.listkeys('namespaces'):
5390 lmarks = repo.listkeys('bookmarks')
5392 lmarks = repo.listkeys('bookmarks')
5391 rmarks = other.listkeys('bookmarks')
5393 rmarks = other.listkeys('bookmarks')
5392 diff = set(rmarks) - set(lmarks)
5394 diff = set(rmarks) - set(lmarks)
5393 if len(diff) > 0:
5395 if len(diff) > 0:
5394 t.append(_('%d incoming bookmarks') % len(diff))
5396 t.append(_('%d incoming bookmarks') % len(diff))
5395 diff = set(lmarks) - set(rmarks)
5397 diff = set(lmarks) - set(rmarks)
5396 if len(diff) > 0:
5398 if len(diff) > 0:
5397 t.append(_('%d outgoing bookmarks') % len(diff))
5399 t.append(_('%d outgoing bookmarks') % len(diff))
5398
5400
5399 if t:
5401 if t:
5400 ui.write(_('remote: %s\n') % (', '.join(t)))
5402 ui.write(_('remote: %s\n') % (', '.join(t)))
5401 else:
5403 else:
5402 ui.status(_('remote: (synced)\n'))
5404 ui.status(_('remote: (synced)\n'))
5403
5405
5404 @command('tag',
5406 @command('tag',
5405 [('f', 'force', None, _('force tag')),
5407 [('f', 'force', None, _('force tag')),
5406 ('l', 'local', None, _('make the tag local')),
5408 ('l', 'local', None, _('make the tag local')),
5407 ('r', 'rev', '', _('revision to tag'), _('REV')),
5409 ('r', 'rev', '', _('revision to tag'), _('REV')),
5408 ('', 'remove', None, _('remove a tag')),
5410 ('', 'remove', None, _('remove a tag')),
5409 # -l/--local is already there, commitopts cannot be used
5411 # -l/--local is already there, commitopts cannot be used
5410 ('e', 'edit', None, _('edit commit message')),
5412 ('e', 'edit', None, _('edit commit message')),
5411 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5413 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5412 ] + commitopts2,
5414 ] + commitopts2,
5413 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5415 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5414 def tag(ui, repo, name1, *names, **opts):
5416 def tag(ui, repo, name1, *names, **opts):
5415 """add one or more tags for the current or given revision
5417 """add one or more tags for the current or given revision
5416
5418
5417 Name a particular revision using <name>.
5419 Name a particular revision using <name>.
5418
5420
5419 Tags are used to name particular revisions of the repository and are
5421 Tags are used to name particular revisions of the repository and are
5420 very useful to compare different revisions, to go back to significant
5422 very useful to compare different revisions, to go back to significant
5421 earlier versions or to mark branch points as releases, etc. Changing
5423 earlier versions or to mark branch points as releases, etc. Changing
5422 an existing tag is normally disallowed; use -f/--force to override.
5424 an existing tag is normally disallowed; use -f/--force to override.
5423
5425
5424 If no revision is given, the parent of the working directory is
5426 If no revision is given, the parent of the working directory is
5425 used, or tip if no revision is checked out.
5427 used, or tip if no revision is checked out.
5426
5428
5427 To facilitate version control, distribution, and merging of tags,
5429 To facilitate version control, distribution, and merging of tags,
5428 they are stored as a file named ".hgtags" which is managed similarly
5430 they are stored as a file named ".hgtags" which is managed similarly
5429 to other project files and can be hand-edited if necessary. This
5431 to other project files and can be hand-edited if necessary. This
5430 also means that tagging creates a new commit. The file
5432 also means that tagging creates a new commit. The file
5431 ".hg/localtags" is used for local tags (not shared among
5433 ".hg/localtags" is used for local tags (not shared among
5432 repositories).
5434 repositories).
5433
5435
5434 Tag commits are usually made at the head of a branch. If the parent
5436 Tag commits are usually made at the head of a branch. If the parent
5435 of the working directory is not a branch head, :hg:`tag` aborts; use
5437 of the working directory is not a branch head, :hg:`tag` aborts; use
5436 -f/--force to force the tag commit to be based on a non-head
5438 -f/--force to force the tag commit to be based on a non-head
5437 changeset.
5439 changeset.
5438
5440
5439 See :hg:`help dates` for a list of formats valid for -d/--date.
5441 See :hg:`help dates` for a list of formats valid for -d/--date.
5440
5442
5441 Since tag names have priority over branch names during revision
5443 Since tag names have priority over branch names during revision
5442 lookup, using an existing branch name as a tag name is discouraged.
5444 lookup, using an existing branch name as a tag name is discouraged.
5443
5445
5444 Returns 0 on success.
5446 Returns 0 on success.
5445 """
5447 """
5446
5448
5447 rev_ = "."
5449 rev_ = "."
5448 names = [t.strip() for t in (name1,) + names]
5450 names = [t.strip() for t in (name1,) + names]
5449 if len(names) != len(set(names)):
5451 if len(names) != len(set(names)):
5450 raise util.Abort(_('tag names must be unique'))
5452 raise util.Abort(_('tag names must be unique'))
5451 for n in names:
5453 for n in names:
5452 if n in ['tip', '.', 'null']:
5454 if n in ['tip', '.', 'null']:
5453 raise util.Abort(_("the name '%s' is reserved") % n)
5455 raise util.Abort(_("the name '%s' is reserved") % n)
5454 if not n:
5456 if not n:
5455 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
5457 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
5456 if opts.get('rev') and opts.get('remove'):
5458 if opts.get('rev') and opts.get('remove'):
5457 raise util.Abort(_("--rev and --remove are incompatible"))
5459 raise util.Abort(_("--rev and --remove are incompatible"))
5458 if opts.get('rev'):
5460 if opts.get('rev'):
5459 rev_ = opts['rev']
5461 rev_ = opts['rev']
5460 message = opts.get('message')
5462 message = opts.get('message')
5461 if opts.get('remove'):
5463 if opts.get('remove'):
5462 expectedtype = opts.get('local') and 'local' or 'global'
5464 expectedtype = opts.get('local') and 'local' or 'global'
5463 for n in names:
5465 for n in names:
5464 if not repo.tagtype(n):
5466 if not repo.tagtype(n):
5465 raise util.Abort(_("tag '%s' does not exist") % n)
5467 raise util.Abort(_("tag '%s' does not exist") % n)
5466 if repo.tagtype(n) != expectedtype:
5468 if repo.tagtype(n) != expectedtype:
5467 if expectedtype == 'global':
5469 if expectedtype == 'global':
5468 raise util.Abort(_("tag '%s' is not a global tag") % n)
5470 raise util.Abort(_("tag '%s' is not a global tag") % n)
5469 else:
5471 else:
5470 raise util.Abort(_("tag '%s' is not a local tag") % n)
5472 raise util.Abort(_("tag '%s' is not a local tag") % n)
5471 rev_ = nullid
5473 rev_ = nullid
5472 if not message:
5474 if not message:
5473 # we don't translate commit messages
5475 # we don't translate commit messages
5474 message = 'Removed tag %s' % ', '.join(names)
5476 message = 'Removed tag %s' % ', '.join(names)
5475 elif not opts.get('force'):
5477 elif not opts.get('force'):
5476 for n in names:
5478 for n in names:
5477 if n in repo.tags():
5479 if n in repo.tags():
5478 raise util.Abort(_("tag '%s' already exists "
5480 raise util.Abort(_("tag '%s' already exists "
5479 "(use -f to force)") % n)
5481 "(use -f to force)") % n)
5480 if not opts.get('local'):
5482 if not opts.get('local'):
5481 p1, p2 = repo.dirstate.parents()
5483 p1, p2 = repo.dirstate.parents()
5482 if p2 != nullid:
5484 if p2 != nullid:
5483 raise util.Abort(_('uncommitted merge'))
5485 raise util.Abort(_('uncommitted merge'))
5484 bheads = repo.branchheads()
5486 bheads = repo.branchheads()
5485 if not opts.get('force') and bheads and p1 not in bheads:
5487 if not opts.get('force') and bheads and p1 not in bheads:
5486 raise util.Abort(_('not at a branch head (use -f to force)'))
5488 raise util.Abort(_('not at a branch head (use -f to force)'))
5487 r = scmutil.revsingle(repo, rev_).node()
5489 r = scmutil.revsingle(repo, rev_).node()
5488
5490
5489 if not message:
5491 if not message:
5490 # we don't translate commit messages
5492 # we don't translate commit messages
5491 message = ('Added tag %s for changeset %s' %
5493 message = ('Added tag %s for changeset %s' %
5492 (', '.join(names), short(r)))
5494 (', '.join(names), short(r)))
5493
5495
5494 date = opts.get('date')
5496 date = opts.get('date')
5495 if date:
5497 if date:
5496 date = util.parsedate(date)
5498 date = util.parsedate(date)
5497
5499
5498 if opts.get('edit'):
5500 if opts.get('edit'):
5499 message = ui.edit(message, ui.username())
5501 message = ui.edit(message, ui.username())
5500
5502
5501 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5503 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5502
5504
5503 @command('tags', [], '')
5505 @command('tags', [], '')
5504 def tags(ui, repo):
5506 def tags(ui, repo):
5505 """list repository tags
5507 """list repository tags
5506
5508
5507 This lists both regular and local tags. When the -v/--verbose
5509 This lists both regular and local tags. When the -v/--verbose
5508 switch is used, a third column "local" is printed for local tags.
5510 switch is used, a third column "local" is printed for local tags.
5509
5511
5510 Returns 0 on success.
5512 Returns 0 on success.
5511 """
5513 """
5512
5514
5513 hexfunc = ui.debugflag and hex or short
5515 hexfunc = ui.debugflag and hex or short
5514 tagtype = ""
5516 tagtype = ""
5515
5517
5516 for t, n in reversed(repo.tagslist()):
5518 for t, n in reversed(repo.tagslist()):
5517 if ui.quiet:
5519 if ui.quiet:
5518 ui.write("%s\n" % t, label='tags.normal')
5520 ui.write("%s\n" % t, label='tags.normal')
5519 continue
5521 continue
5520
5522
5521 hn = hexfunc(n)
5523 hn = hexfunc(n)
5522 r = "%5d:%s" % (repo.changelog.rev(n), hn)
5524 r = "%5d:%s" % (repo.changelog.rev(n), hn)
5523 rev = ui.label(r, 'log.changeset')
5525 rev = ui.label(r, 'log.changeset')
5524 spaces = " " * (30 - encoding.colwidth(t))
5526 spaces = " " * (30 - encoding.colwidth(t))
5525
5527
5526 tag = ui.label(t, 'tags.normal')
5528 tag = ui.label(t, 'tags.normal')
5527 if ui.verbose:
5529 if ui.verbose:
5528 if repo.tagtype(t) == 'local':
5530 if repo.tagtype(t) == 'local':
5529 tagtype = " local"
5531 tagtype = " local"
5530 tag = ui.label(t, 'tags.local')
5532 tag = ui.label(t, 'tags.local')
5531 else:
5533 else:
5532 tagtype = ""
5534 tagtype = ""
5533 ui.write("%s%s %s%s\n" % (tag, spaces, rev, tagtype))
5535 ui.write("%s%s %s%s\n" % (tag, spaces, rev, tagtype))
5534
5536
5535 @command('tip',
5537 @command('tip',
5536 [('p', 'patch', None, _('show patch')),
5538 [('p', 'patch', None, _('show patch')),
5537 ('g', 'git', None, _('use git extended diff format')),
5539 ('g', 'git', None, _('use git extended diff format')),
5538 ] + templateopts,
5540 ] + templateopts,
5539 _('[-p] [-g]'))
5541 _('[-p] [-g]'))
5540 def tip(ui, repo, **opts):
5542 def tip(ui, repo, **opts):
5541 """show the tip revision
5543 """show the tip revision
5542
5544
5543 The tip revision (usually just called the tip) is the changeset
5545 The tip revision (usually just called the tip) is the changeset
5544 most recently added to the repository (and therefore the most
5546 most recently added to the repository (and therefore the most
5545 recently changed head).
5547 recently changed head).
5546
5548
5547 If you have just made a commit, that commit will be the tip. If
5549 If you have just made a commit, that commit will be the tip. If
5548 you have just pulled changes from another repository, the tip of
5550 you have just pulled changes from another repository, the tip of
5549 that repository becomes the current tip. The "tip" tag is special
5551 that repository becomes the current tip. The "tip" tag is special
5550 and cannot be renamed or assigned to a different changeset.
5552 and cannot be renamed or assigned to a different changeset.
5551
5553
5552 Returns 0 on success.
5554 Returns 0 on success.
5553 """
5555 """
5554 displayer = cmdutil.show_changeset(ui, repo, opts)
5556 displayer = cmdutil.show_changeset(ui, repo, opts)
5555 displayer.show(repo[len(repo) - 1])
5557 displayer.show(repo[len(repo) - 1])
5556 displayer.close()
5558 displayer.close()
5557
5559
5558 @command('unbundle',
5560 @command('unbundle',
5559 [('u', 'update', None,
5561 [('u', 'update', None,
5560 _('update to new branch head if changesets were unbundled'))],
5562 _('update to new branch head if changesets were unbundled'))],
5561 _('[-u] FILE...'))
5563 _('[-u] FILE...'))
5562 def unbundle(ui, repo, fname1, *fnames, **opts):
5564 def unbundle(ui, repo, fname1, *fnames, **opts):
5563 """apply one or more changegroup files
5565 """apply one or more changegroup files
5564
5566
5565 Apply one or more compressed changegroup files generated by the
5567 Apply one or more compressed changegroup files generated by the
5566 bundle command.
5568 bundle command.
5567
5569
5568 Returns 0 on success, 1 if an update has unresolved files.
5570 Returns 0 on success, 1 if an update has unresolved files.
5569 """
5571 """
5570 fnames = (fname1,) + fnames
5572 fnames = (fname1,) + fnames
5571
5573
5572 lock = repo.lock()
5574 lock = repo.lock()
5573 wc = repo['.']
5575 wc = repo['.']
5574 try:
5576 try:
5575 for fname in fnames:
5577 for fname in fnames:
5576 f = url.open(ui, fname)
5578 f = url.open(ui, fname)
5577 gen = changegroup.readbundle(f, fname)
5579 gen = changegroup.readbundle(f, fname)
5578 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5580 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5579 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5581 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5580 finally:
5582 finally:
5581 lock.release()
5583 lock.release()
5582 return postincoming(ui, repo, modheads, opts.get('update'), None)
5584 return postincoming(ui, repo, modheads, opts.get('update'), None)
5583
5585
5584 @command('^update|up|checkout|co',
5586 @command('^update|up|checkout|co',
5585 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5587 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5586 ('c', 'check', None,
5588 ('c', 'check', None,
5587 _('update across branches if no uncommitted changes')),
5589 _('update across branches if no uncommitted changes')),
5588 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5590 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5589 ('r', 'rev', '', _('revision'), _('REV'))],
5591 ('r', 'rev', '', _('revision'), _('REV'))],
5590 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5592 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5591 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5593 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5592 """update working directory (or switch revisions)
5594 """update working directory (or switch revisions)
5593
5595
5594 Update the repository's working directory to the specified
5596 Update the repository's working directory to the specified
5595 changeset. If no changeset is specified, update to the tip of the
5597 changeset. If no changeset is specified, update to the tip of the
5596 current named branch.
5598 current named branch.
5597
5599
5598 If the changeset is not a descendant of the working directory's
5600 If the changeset is not a descendant of the working directory's
5599 parent, the update is aborted. With the -c/--check option, the
5601 parent, the update is aborted. With the -c/--check option, the
5600 working directory is checked for uncommitted changes; if none are
5602 working directory is checked for uncommitted changes; if none are
5601 found, the working directory is updated to the specified
5603 found, the working directory is updated to the specified
5602 changeset.
5604 changeset.
5603
5605
5604 Update sets the working directory's parent revison to the specified
5606 Update sets the working directory's parent revison to the specified
5605 changeset (see :hg:`help parents`).
5607 changeset (see :hg:`help parents`).
5606
5608
5607 The following rules apply when the working directory contains
5609 The following rules apply when the working directory contains
5608 uncommitted changes:
5610 uncommitted changes:
5609
5611
5610 1. If neither -c/--check nor -C/--clean is specified, and if
5612 1. If neither -c/--check nor -C/--clean is specified, and if
5611 the requested changeset is an ancestor or descendant of
5613 the requested changeset is an ancestor or descendant of
5612 the working directory's parent, the uncommitted changes
5614 the working directory's parent, the uncommitted changes
5613 are merged into the requested changeset and the merged
5615 are merged into the requested changeset and the merged
5614 result is left uncommitted. If the requested changeset is
5616 result is left uncommitted. If the requested changeset is
5615 not an ancestor or descendant (that is, it is on another
5617 not an ancestor or descendant (that is, it is on another
5616 branch), the update is aborted and the uncommitted changes
5618 branch), the update is aborted and the uncommitted changes
5617 are preserved.
5619 are preserved.
5618
5620
5619 2. With the -c/--check option, the update is aborted and the
5621 2. With the -c/--check option, the update is aborted and the
5620 uncommitted changes are preserved.
5622 uncommitted changes are preserved.
5621
5623
5622 3. With the -C/--clean option, uncommitted changes are discarded and
5624 3. With the -C/--clean option, uncommitted changes are discarded and
5623 the working directory is updated to the requested changeset.
5625 the working directory is updated to the requested changeset.
5624
5626
5625 Use null as the changeset to remove the working directory (like
5627 Use null as the changeset to remove the working directory (like
5626 :hg:`clone -U`).
5628 :hg:`clone -U`).
5627
5629
5628 If you want to revert just one file to an older revision, use
5630 If you want to revert just one file to an older revision, use
5629 :hg:`revert [-r REV] NAME`.
5631 :hg:`revert [-r REV] NAME`.
5630
5632
5631 See :hg:`help dates` for a list of formats valid for -d/--date.
5633 See :hg:`help dates` for a list of formats valid for -d/--date.
5632
5634
5633 Returns 0 on success, 1 if there are unresolved files.
5635 Returns 0 on success, 1 if there are unresolved files.
5634 """
5636 """
5635 if rev and node:
5637 if rev and node:
5636 raise util.Abort(_("please specify just one revision"))
5638 raise util.Abort(_("please specify just one revision"))
5637
5639
5638 if rev is None or rev == '':
5640 if rev is None or rev == '':
5639 rev = node
5641 rev = node
5640
5642
5641 # if we defined a bookmark, we have to remember the original bookmark name
5643 # if we defined a bookmark, we have to remember the original bookmark name
5642 brev = rev
5644 brev = rev
5643 rev = scmutil.revsingle(repo, rev, rev).rev()
5645 rev = scmutil.revsingle(repo, rev, rev).rev()
5644
5646
5645 if check and clean:
5647 if check and clean:
5646 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5648 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5647
5649
5648 if check:
5650 if check:
5649 # we could use dirty() but we can ignore merge and branch trivia
5651 # we could use dirty() but we can ignore merge and branch trivia
5650 c = repo[None]
5652 c = repo[None]
5651 if c.modified() or c.added() or c.removed():
5653 if c.modified() or c.added() or c.removed():
5652 raise util.Abort(_("uncommitted local changes"))
5654 raise util.Abort(_("uncommitted local changes"))
5653
5655
5654 if date:
5656 if date:
5655 if rev is not None:
5657 if rev is not None:
5656 raise util.Abort(_("you can't specify a revision and a date"))
5658 raise util.Abort(_("you can't specify a revision and a date"))
5657 rev = cmdutil.finddate(ui, repo, date)
5659 rev = cmdutil.finddate(ui, repo, date)
5658
5660
5659 if clean or check:
5661 if clean or check:
5660 ret = hg.clean(repo, rev)
5662 ret = hg.clean(repo, rev)
5661 else:
5663 else:
5662 ret = hg.update(repo, rev)
5664 ret = hg.update(repo, rev)
5663
5665
5664 if brev in repo._bookmarks:
5666 if brev in repo._bookmarks:
5665 bookmarks.setcurrent(repo, brev)
5667 bookmarks.setcurrent(repo, brev)
5666
5668
5667 return ret
5669 return ret
5668
5670
5669 @command('verify', [])
5671 @command('verify', [])
5670 def verify(ui, repo):
5672 def verify(ui, repo):
5671 """verify the integrity of the repository
5673 """verify the integrity of the repository
5672
5674
5673 Verify the integrity of the current repository.
5675 Verify the integrity of the current repository.
5674
5676
5675 This will perform an extensive check of the repository's
5677 This will perform an extensive check of the repository's
5676 integrity, validating the hashes and checksums of each entry in
5678 integrity, validating the hashes and checksums of each entry in
5677 the changelog, manifest, and tracked files, as well as the
5679 the changelog, manifest, and tracked files, as well as the
5678 integrity of their crosslinks and indices.
5680 integrity of their crosslinks and indices.
5679
5681
5680 Returns 0 on success, 1 if errors are encountered.
5682 Returns 0 on success, 1 if errors are encountered.
5681 """
5683 """
5682 return hg.verify(repo)
5684 return hg.verify(repo)
5683
5685
5684 @command('version', [])
5686 @command('version', [])
5685 def version_(ui):
5687 def version_(ui):
5686 """output version and copyright information"""
5688 """output version and copyright information"""
5687 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5689 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5688 % util.version())
5690 % util.version())
5689 ui.status(_(
5691 ui.status(_(
5690 "(see http://mercurial.selenic.com for more information)\n"
5692 "(see http://mercurial.selenic.com for more information)\n"
5691 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
5693 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
5692 "This is free software; see the source for copying conditions. "
5694 "This is free software; see the source for copying conditions. "
5693 "There is NO\nwarranty; "
5695 "There is NO\nwarranty; "
5694 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5696 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5695 ))
5697 ))
5696
5698
5697 norepo = ("clone init version help debugcommands debugcomplete"
5699 norepo = ("clone init version help debugcommands debugcomplete"
5698 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5700 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5699 " debugknown debuggetbundle debugbundle")
5701 " debugknown debuggetbundle debugbundle")
5700 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
5702 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
5701 " debugdata debugindex debugindexdot debugrevlog")
5703 " debugdata debugindex debugindexdot debugrevlog")
@@ -1,1923 +1,1924 b''
1 > do_push()
1 > do_push()
2 > {
2 > {
3 > user=$1
3 > user=$1
4 > shift
4 > shift
5 > echo "Pushing as user $user"
5 > echo "Pushing as user $user"
6 > echo 'hgrc = """'
6 > echo 'hgrc = """'
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
8 > echo '"""'
8 > echo '"""'
9 > if test -f acl.config; then
9 > if test -f acl.config; then
10 > echo 'acl.config = """'
10 > echo 'acl.config = """'
11 > cat acl.config
11 > cat acl.config
12 > echo '"""'
12 > echo '"""'
13 > fi
13 > fi
14 > # On AIX /etc/profile sets LOGNAME read-only. So
14 > # On AIX /etc/profile sets LOGNAME read-only. So
15 > # LOGNAME=$user hg --cws a --debug push ../b
15 > # LOGNAME=$user hg --cws a --debug push ../b
16 > # fails with "This variable is read only."
16 > # fails with "This variable is read only."
17 > # Use env to work around this.
17 > # Use env to work around this.
18 > env LOGNAME=$user hg --cwd a --debug push ../b
18 > env LOGNAME=$user hg --cwd a --debug push ../b
19 > hg --cwd b rollback
19 > hg --cwd b rollback
20 > hg --cwd b --quiet tip
20 > hg --cwd b --quiet tip
21 > echo
21 > echo
22 > }
22 > }
23
23
24 > init_config()
24 > init_config()
25 > {
25 > {
26 > cat > fakegroups.py <<EOF
26 > cat > fakegroups.py <<EOF
27 > from hgext import acl
27 > from hgext import acl
28 > def fakegetusers(ui, group):
28 > def fakegetusers(ui, group):
29 > try:
29 > try:
30 > return acl._getusersorig(ui, group)
30 > return acl._getusersorig(ui, group)
31 > except:
31 > except:
32 > return ["fred", "betty"]
32 > return ["fred", "betty"]
33 > acl._getusersorig = acl._getusers
33 > acl._getusersorig = acl._getusers
34 > acl._getusers = fakegetusers
34 > acl._getusers = fakegetusers
35 > EOF
35 > EOF
36 > rm -f acl.config
36 > rm -f acl.config
37 > cat > $config <<EOF
37 > cat > $config <<EOF
38 > [hooks]
38 > [hooks]
39 > pretxnchangegroup.acl = python:hgext.acl.hook
39 > pretxnchangegroup.acl = python:hgext.acl.hook
40 > [acl]
40 > [acl]
41 > sources = push
41 > sources = push
42 > [extensions]
42 > [extensions]
43 > f=`pwd`/fakegroups.py
43 > f=`pwd`/fakegroups.py
44 > EOF
44 > EOF
45 > }
45 > }
46
46
47 $ hg init a
47 $ hg init a
48 $ cd a
48 $ cd a
49 $ mkdir foo foo/Bar quux
49 $ mkdir foo foo/Bar quux
50 $ echo 'in foo' > foo/file.txt
50 $ echo 'in foo' > foo/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
52 $ echo 'in quux' > quux/file.py
52 $ echo 'in quux' > quux/file.py
53 $ hg add -q
53 $ hg add -q
54 $ hg ci -m 'add files' -d '1000000 0'
54 $ hg ci -m 'add files' -d '1000000 0'
55 $ echo >> foo/file.txt
55 $ echo >> foo/file.txt
56 $ hg ci -m 'change foo/file' -d '1000001 0'
56 $ hg ci -m 'change foo/file' -d '1000001 0'
57 $ echo >> foo/Bar/file.txt
57 $ echo >> foo/Bar/file.txt
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
59 $ echo >> quux/file.py
59 $ echo >> quux/file.py
60 $ hg ci -m 'change quux/file' -d '1000003 0'
60 $ hg ci -m 'change quux/file' -d '1000003 0'
61 $ hg tip --quiet
61 $ hg tip --quiet
62 3:911600dab2ae
62 3:911600dab2ae
63
63
64 $ cd ..
64 $ cd ..
65 $ hg clone -r 0 a b
65 $ hg clone -r 0 a b
66 adding changesets
66 adding changesets
67 adding manifests
67 adding manifests
68 adding file changes
68 adding file changes
69 added 1 changesets with 3 changes to 3 files
69 added 1 changesets with 3 changes to 3 files
70 updating to branch default
70 updating to branch default
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
72
72
73 $ echo '[extensions]' >> $HGRCPATH
73 $ echo '[extensions]' >> $HGRCPATH
74 $ echo 'acl =' >> $HGRCPATH
74 $ echo 'acl =' >> $HGRCPATH
75
75
76 $ config=b/.hg/hgrc
76 $ config=b/.hg/hgrc
77
77
78 Extension disabled for lack of a hook
78 Extension disabled for lack of a hook
79
79
80 $ do_push fred
80 $ do_push fred
81 Pushing as user fred
81 Pushing as user fred
82 hgrc = """
82 hgrc = """
83 """
83 """
84 pushing to ../b
84 pushing to ../b
85 query 1; heads
85 query 1; heads
86 searching for changes
86 searching for changes
87 all remote heads known locally
87 all remote heads known locally
88 3 changesets found
88 3 changesets found
89 list of changesets:
89 list of changesets:
90 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
90 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
91 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
91 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
92 911600dab2ae7a9baff75958b84fe606851ce955
92 911600dab2ae7a9baff75958b84fe606851ce955
93 adding changesets
93 adding changesets
94 bundling: 1/3 changesets (33.33%)
94 bundling: 1/3 changesets (33.33%)
95 bundling: 2/3 changesets (66.67%)
95 bundling: 2/3 changesets (66.67%)
96 bundling: 3/3 changesets (100.00%)
96 bundling: 3/3 changesets (100.00%)
97 bundling: 1/3 manifests (33.33%)
97 bundling: 1/3 manifests (33.33%)
98 bundling: 2/3 manifests (66.67%)
98 bundling: 2/3 manifests (66.67%)
99 bundling: 3/3 manifests (100.00%)
99 bundling: 3/3 manifests (100.00%)
100 bundling: foo/Bar/file.txt 1/3 files (33.33%)
100 bundling: foo/Bar/file.txt 1/3 files (33.33%)
101 bundling: foo/file.txt 2/3 files (66.67%)
101 bundling: foo/file.txt 2/3 files (66.67%)
102 bundling: quux/file.py 3/3 files (100.00%)
102 bundling: quux/file.py 3/3 files (100.00%)
103 changesets: 1 chunks
103 changesets: 1 chunks
104 add changeset ef1ea85a6374
104 add changeset ef1ea85a6374
105 changesets: 2 chunks
105 changesets: 2 chunks
106 add changeset f9cafe1212c8
106 add changeset f9cafe1212c8
107 changesets: 3 chunks
107 changesets: 3 chunks
108 add changeset 911600dab2ae
108 add changeset 911600dab2ae
109 adding manifests
109 adding manifests
110 manifests: 1/3 chunks (33.33%)
110 manifests: 1/3 chunks (33.33%)
111 manifests: 2/3 chunks (66.67%)
111 manifests: 2/3 chunks (66.67%)
112 manifests: 3/3 chunks (100.00%)
112 manifests: 3/3 chunks (100.00%)
113 adding file changes
113 adding file changes
114 adding foo/Bar/file.txt revisions
114 adding foo/Bar/file.txt revisions
115 files: 1/3 chunks (33.33%)
115 files: 1/3 chunks (33.33%)
116 adding foo/file.txt revisions
116 adding foo/file.txt revisions
117 files: 2/3 chunks (66.67%)
117 files: 2/3 chunks (66.67%)
118 adding quux/file.py revisions
118 adding quux/file.py revisions
119 files: 3/3 chunks (100.00%)
119 files: 3/3 chunks (100.00%)
120 added 3 changesets with 3 changes to 3 files
120 added 3 changesets with 3 changes to 3 files
121 updating the branch cache
121 updating the branch cache
122 checking for updated bookmarks
122 checking for updated bookmarks
123 repository tip rolled back to revision 0 (undo push)
123 repository tip rolled back to revision 0 (undo push)
124 0:6675d58eff77
124 0:6675d58eff77
125
125
126
126
127 $ echo '[hooks]' >> $config
127 $ echo '[hooks]' >> $config
128 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
128 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
129
129
130 Extension disabled for lack of acl.sources
130 Extension disabled for lack of acl.sources
131
131
132 $ do_push fred
132 $ do_push fred
133 Pushing as user fred
133 Pushing as user fred
134 hgrc = """
134 hgrc = """
135 [hooks]
135 [hooks]
136 pretxnchangegroup.acl = python:hgext.acl.hook
136 pretxnchangegroup.acl = python:hgext.acl.hook
137 """
137 """
138 pushing to ../b
138 pushing to ../b
139 query 1; heads
139 query 1; heads
140 searching for changes
140 searching for changes
141 all remote heads known locally
141 all remote heads known locally
142 invalidating branch cache (tip differs)
142 invalidating branch cache (tip differs)
143 3 changesets found
143 3 changesets found
144 list of changesets:
144 list of changesets:
145 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
145 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
146 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
146 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
147 911600dab2ae7a9baff75958b84fe606851ce955
147 911600dab2ae7a9baff75958b84fe606851ce955
148 adding changesets
148 adding changesets
149 bundling: 1/3 changesets (33.33%)
149 bundling: 1/3 changesets (33.33%)
150 bundling: 2/3 changesets (66.67%)
150 bundling: 2/3 changesets (66.67%)
151 bundling: 3/3 changesets (100.00%)
151 bundling: 3/3 changesets (100.00%)
152 bundling: 1/3 manifests (33.33%)
152 bundling: 1/3 manifests (33.33%)
153 bundling: 2/3 manifests (66.67%)
153 bundling: 2/3 manifests (66.67%)
154 bundling: 3/3 manifests (100.00%)
154 bundling: 3/3 manifests (100.00%)
155 bundling: foo/Bar/file.txt 1/3 files (33.33%)
155 bundling: foo/Bar/file.txt 1/3 files (33.33%)
156 bundling: foo/file.txt 2/3 files (66.67%)
156 bundling: foo/file.txt 2/3 files (66.67%)
157 bundling: quux/file.py 3/3 files (100.00%)
157 bundling: quux/file.py 3/3 files (100.00%)
158 changesets: 1 chunks
158 changesets: 1 chunks
159 add changeset ef1ea85a6374
159 add changeset ef1ea85a6374
160 changesets: 2 chunks
160 changesets: 2 chunks
161 add changeset f9cafe1212c8
161 add changeset f9cafe1212c8
162 changesets: 3 chunks
162 changesets: 3 chunks
163 add changeset 911600dab2ae
163 add changeset 911600dab2ae
164 adding manifests
164 adding manifests
165 manifests: 1/3 chunks (33.33%)
165 manifests: 1/3 chunks (33.33%)
166 manifests: 2/3 chunks (66.67%)
166 manifests: 2/3 chunks (66.67%)
167 manifests: 3/3 chunks (100.00%)
167 manifests: 3/3 chunks (100.00%)
168 adding file changes
168 adding file changes
169 adding foo/Bar/file.txt revisions
169 adding foo/Bar/file.txt revisions
170 files: 1/3 chunks (33.33%)
170 files: 1/3 chunks (33.33%)
171 adding foo/file.txt revisions
171 adding foo/file.txt revisions
172 files: 2/3 chunks (66.67%)
172 files: 2/3 chunks (66.67%)
173 adding quux/file.py revisions
173 adding quux/file.py revisions
174 files: 3/3 chunks (100.00%)
174 files: 3/3 chunks (100.00%)
175 added 3 changesets with 3 changes to 3 files
175 added 3 changesets with 3 changes to 3 files
176 calling hook pretxnchangegroup.acl: hgext.acl.hook
176 calling hook pretxnchangegroup.acl: hgext.acl.hook
177 acl: changes have source "push" - skipping
177 acl: changes have source "push" - skipping
178 updating the branch cache
178 updating the branch cache
179 checking for updated bookmarks
179 checking for updated bookmarks
180 repository tip rolled back to revision 0 (undo push)
180 repository tip rolled back to revision 0 (undo push)
181 0:6675d58eff77
181 0:6675d58eff77
182
182
183
183
184 No [acl.allow]/[acl.deny]
184 No [acl.allow]/[acl.deny]
185
185
186 $ echo '[acl]' >> $config
186 $ echo '[acl]' >> $config
187 $ echo 'sources = push' >> $config
187 $ echo 'sources = push' >> $config
188 $ do_push fred
188 $ do_push fred
189 Pushing as user fred
189 Pushing as user fred
190 hgrc = """
190 hgrc = """
191 [hooks]
191 [hooks]
192 pretxnchangegroup.acl = python:hgext.acl.hook
192 pretxnchangegroup.acl = python:hgext.acl.hook
193 [acl]
193 [acl]
194 sources = push
194 sources = push
195 """
195 """
196 pushing to ../b
196 pushing to ../b
197 query 1; heads
197 query 1; heads
198 searching for changes
198 searching for changes
199 all remote heads known locally
199 all remote heads known locally
200 invalidating branch cache (tip differs)
200 invalidating branch cache (tip differs)
201 3 changesets found
201 3 changesets found
202 list of changesets:
202 list of changesets:
203 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
203 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
204 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
204 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
205 911600dab2ae7a9baff75958b84fe606851ce955
205 911600dab2ae7a9baff75958b84fe606851ce955
206 adding changesets
206 adding changesets
207 bundling: 1/3 changesets (33.33%)
207 bundling: 1/3 changesets (33.33%)
208 bundling: 2/3 changesets (66.67%)
208 bundling: 2/3 changesets (66.67%)
209 bundling: 3/3 changesets (100.00%)
209 bundling: 3/3 changesets (100.00%)
210 bundling: 1/3 manifests (33.33%)
210 bundling: 1/3 manifests (33.33%)
211 bundling: 2/3 manifests (66.67%)
211 bundling: 2/3 manifests (66.67%)
212 bundling: 3/3 manifests (100.00%)
212 bundling: 3/3 manifests (100.00%)
213 bundling: foo/Bar/file.txt 1/3 files (33.33%)
213 bundling: foo/Bar/file.txt 1/3 files (33.33%)
214 bundling: foo/file.txt 2/3 files (66.67%)
214 bundling: foo/file.txt 2/3 files (66.67%)
215 bundling: quux/file.py 3/3 files (100.00%)
215 bundling: quux/file.py 3/3 files (100.00%)
216 changesets: 1 chunks
216 changesets: 1 chunks
217 add changeset ef1ea85a6374
217 add changeset ef1ea85a6374
218 changesets: 2 chunks
218 changesets: 2 chunks
219 add changeset f9cafe1212c8
219 add changeset f9cafe1212c8
220 changesets: 3 chunks
220 changesets: 3 chunks
221 add changeset 911600dab2ae
221 add changeset 911600dab2ae
222 adding manifests
222 adding manifests
223 manifests: 1/3 chunks (33.33%)
223 manifests: 1/3 chunks (33.33%)
224 manifests: 2/3 chunks (66.67%)
224 manifests: 2/3 chunks (66.67%)
225 manifests: 3/3 chunks (100.00%)
225 manifests: 3/3 chunks (100.00%)
226 adding file changes
226 adding file changes
227 adding foo/Bar/file.txt revisions
227 adding foo/Bar/file.txt revisions
228 files: 1/3 chunks (33.33%)
228 files: 1/3 chunks (33.33%)
229 adding foo/file.txt revisions
229 adding foo/file.txt revisions
230 files: 2/3 chunks (66.67%)
230 files: 2/3 chunks (66.67%)
231 adding quux/file.py revisions
231 adding quux/file.py revisions
232 files: 3/3 chunks (100.00%)
232 files: 3/3 chunks (100.00%)
233 added 3 changesets with 3 changes to 3 files
233 added 3 changesets with 3 changes to 3 files
234 calling hook pretxnchangegroup.acl: hgext.acl.hook
234 calling hook pretxnchangegroup.acl: hgext.acl.hook
235 acl: checking access for user "fred"
235 acl: checking access for user "fred"
236 acl: acl.allow.branches not enabled
236 acl: acl.allow.branches not enabled
237 acl: acl.deny.branches not enabled
237 acl: acl.deny.branches not enabled
238 acl: acl.allow not enabled
238 acl: acl.allow not enabled
239 acl: acl.deny not enabled
239 acl: acl.deny not enabled
240 acl: branch access granted: "ef1ea85a6374" on branch "default"
240 acl: branch access granted: "ef1ea85a6374" on branch "default"
241 acl: path access granted: "ef1ea85a6374"
241 acl: path access granted: "ef1ea85a6374"
242 acl: branch access granted: "f9cafe1212c8" on branch "default"
242 acl: branch access granted: "f9cafe1212c8" on branch "default"
243 acl: path access granted: "f9cafe1212c8"
243 acl: path access granted: "f9cafe1212c8"
244 acl: branch access granted: "911600dab2ae" on branch "default"
244 acl: branch access granted: "911600dab2ae" on branch "default"
245 acl: path access granted: "911600dab2ae"
245 acl: path access granted: "911600dab2ae"
246 updating the branch cache
246 updating the branch cache
247 checking for updated bookmarks
247 checking for updated bookmarks
248 repository tip rolled back to revision 0 (undo push)
248 repository tip rolled back to revision 0 (undo push)
249 0:6675d58eff77
249 0:6675d58eff77
250
250
251
251
252 Empty [acl.allow]
252 Empty [acl.allow]
253
253
254 $ echo '[acl.allow]' >> $config
254 $ echo '[acl.allow]' >> $config
255 $ do_push fred
255 $ do_push fred
256 Pushing as user fred
256 Pushing as user fred
257 hgrc = """
257 hgrc = """
258 [hooks]
258 [hooks]
259 pretxnchangegroup.acl = python:hgext.acl.hook
259 pretxnchangegroup.acl = python:hgext.acl.hook
260 [acl]
260 [acl]
261 sources = push
261 sources = push
262 [acl.allow]
262 [acl.allow]
263 """
263 """
264 pushing to ../b
264 pushing to ../b
265 query 1; heads
265 query 1; heads
266 searching for changes
266 searching for changes
267 all remote heads known locally
267 all remote heads known locally
268 invalidating branch cache (tip differs)
268 invalidating branch cache (tip differs)
269 3 changesets found
269 3 changesets found
270 list of changesets:
270 list of changesets:
271 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
271 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
272 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
272 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
273 911600dab2ae7a9baff75958b84fe606851ce955
273 911600dab2ae7a9baff75958b84fe606851ce955
274 adding changesets
274 adding changesets
275 bundling: 1/3 changesets (33.33%)
275 bundling: 1/3 changesets (33.33%)
276 bundling: 2/3 changesets (66.67%)
276 bundling: 2/3 changesets (66.67%)
277 bundling: 3/3 changesets (100.00%)
277 bundling: 3/3 changesets (100.00%)
278 bundling: 1/3 manifests (33.33%)
278 bundling: 1/3 manifests (33.33%)
279 bundling: 2/3 manifests (66.67%)
279 bundling: 2/3 manifests (66.67%)
280 bundling: 3/3 manifests (100.00%)
280 bundling: 3/3 manifests (100.00%)
281 bundling: foo/Bar/file.txt 1/3 files (33.33%)
281 bundling: foo/Bar/file.txt 1/3 files (33.33%)
282 bundling: foo/file.txt 2/3 files (66.67%)
282 bundling: foo/file.txt 2/3 files (66.67%)
283 bundling: quux/file.py 3/3 files (100.00%)
283 bundling: quux/file.py 3/3 files (100.00%)
284 changesets: 1 chunks
284 changesets: 1 chunks
285 add changeset ef1ea85a6374
285 add changeset ef1ea85a6374
286 changesets: 2 chunks
286 changesets: 2 chunks
287 add changeset f9cafe1212c8
287 add changeset f9cafe1212c8
288 changesets: 3 chunks
288 changesets: 3 chunks
289 add changeset 911600dab2ae
289 add changeset 911600dab2ae
290 adding manifests
290 adding manifests
291 manifests: 1/3 chunks (33.33%)
291 manifests: 1/3 chunks (33.33%)
292 manifests: 2/3 chunks (66.67%)
292 manifests: 2/3 chunks (66.67%)
293 manifests: 3/3 chunks (100.00%)
293 manifests: 3/3 chunks (100.00%)
294 adding file changes
294 adding file changes
295 adding foo/Bar/file.txt revisions
295 adding foo/Bar/file.txt revisions
296 files: 1/3 chunks (33.33%)
296 files: 1/3 chunks (33.33%)
297 adding foo/file.txt revisions
297 adding foo/file.txt revisions
298 files: 2/3 chunks (66.67%)
298 files: 2/3 chunks (66.67%)
299 adding quux/file.py revisions
299 adding quux/file.py revisions
300 files: 3/3 chunks (100.00%)
300 files: 3/3 chunks (100.00%)
301 added 3 changesets with 3 changes to 3 files
301 added 3 changesets with 3 changes to 3 files
302 calling hook pretxnchangegroup.acl: hgext.acl.hook
302 calling hook pretxnchangegroup.acl: hgext.acl.hook
303 acl: checking access for user "fred"
303 acl: checking access for user "fred"
304 acl: acl.allow.branches not enabled
304 acl: acl.allow.branches not enabled
305 acl: acl.deny.branches not enabled
305 acl: acl.deny.branches not enabled
306 acl: acl.allow enabled, 0 entries for user fred
306 acl: acl.allow enabled, 0 entries for user fred
307 acl: acl.deny not enabled
307 acl: acl.deny not enabled
308 acl: branch access granted: "ef1ea85a6374" on branch "default"
308 acl: branch access granted: "ef1ea85a6374" on branch "default"
309 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
309 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
310 transaction abort!
310 transaction abort!
311 rollback completed
311 rollback completed
312 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
312 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
313 no rollback information available
313 no rollback information available
314 0:6675d58eff77
314 0:6675d58eff77
315
315
316
316
317 fred is allowed inside foo/
317 fred is allowed inside foo/
318
318
319 $ echo 'foo/** = fred' >> $config
319 $ echo 'foo/** = fred' >> $config
320 $ do_push fred
320 $ do_push fred
321 Pushing as user fred
321 Pushing as user fred
322 hgrc = """
322 hgrc = """
323 [hooks]
323 [hooks]
324 pretxnchangegroup.acl = python:hgext.acl.hook
324 pretxnchangegroup.acl = python:hgext.acl.hook
325 [acl]
325 [acl]
326 sources = push
326 sources = push
327 [acl.allow]
327 [acl.allow]
328 foo/** = fred
328 foo/** = fred
329 """
329 """
330 pushing to ../b
330 pushing to ../b
331 query 1; heads
331 query 1; heads
332 searching for changes
332 searching for changes
333 all remote heads known locally
333 all remote heads known locally
334 3 changesets found
334 3 changesets found
335 list of changesets:
335 list of changesets:
336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
338 911600dab2ae7a9baff75958b84fe606851ce955
338 911600dab2ae7a9baff75958b84fe606851ce955
339 adding changesets
339 adding changesets
340 bundling: 1/3 changesets (33.33%)
340 bundling: 1/3 changesets (33.33%)
341 bundling: 2/3 changesets (66.67%)
341 bundling: 2/3 changesets (66.67%)
342 bundling: 3/3 changesets (100.00%)
342 bundling: 3/3 changesets (100.00%)
343 bundling: 1/3 manifests (33.33%)
343 bundling: 1/3 manifests (33.33%)
344 bundling: 2/3 manifests (66.67%)
344 bundling: 2/3 manifests (66.67%)
345 bundling: 3/3 manifests (100.00%)
345 bundling: 3/3 manifests (100.00%)
346 bundling: foo/Bar/file.txt 1/3 files (33.33%)
346 bundling: foo/Bar/file.txt 1/3 files (33.33%)
347 bundling: foo/file.txt 2/3 files (66.67%)
347 bundling: foo/file.txt 2/3 files (66.67%)
348 bundling: quux/file.py 3/3 files (100.00%)
348 bundling: quux/file.py 3/3 files (100.00%)
349 changesets: 1 chunks
349 changesets: 1 chunks
350 add changeset ef1ea85a6374
350 add changeset ef1ea85a6374
351 changesets: 2 chunks
351 changesets: 2 chunks
352 add changeset f9cafe1212c8
352 add changeset f9cafe1212c8
353 changesets: 3 chunks
353 changesets: 3 chunks
354 add changeset 911600dab2ae
354 add changeset 911600dab2ae
355 adding manifests
355 adding manifests
356 manifests: 1/3 chunks (33.33%)
356 manifests: 1/3 chunks (33.33%)
357 manifests: 2/3 chunks (66.67%)
357 manifests: 2/3 chunks (66.67%)
358 manifests: 3/3 chunks (100.00%)
358 manifests: 3/3 chunks (100.00%)
359 adding file changes
359 adding file changes
360 adding foo/Bar/file.txt revisions
360 adding foo/Bar/file.txt revisions
361 files: 1/3 chunks (33.33%)
361 files: 1/3 chunks (33.33%)
362 adding foo/file.txt revisions
362 adding foo/file.txt revisions
363 files: 2/3 chunks (66.67%)
363 files: 2/3 chunks (66.67%)
364 adding quux/file.py revisions
364 adding quux/file.py revisions
365 files: 3/3 chunks (100.00%)
365 files: 3/3 chunks (100.00%)
366 added 3 changesets with 3 changes to 3 files
366 added 3 changesets with 3 changes to 3 files
367 calling hook pretxnchangegroup.acl: hgext.acl.hook
367 calling hook pretxnchangegroup.acl: hgext.acl.hook
368 acl: checking access for user "fred"
368 acl: checking access for user "fred"
369 acl: acl.allow.branches not enabled
369 acl: acl.allow.branches not enabled
370 acl: acl.deny.branches not enabled
370 acl: acl.deny.branches not enabled
371 acl: acl.allow enabled, 1 entries for user fred
371 acl: acl.allow enabled, 1 entries for user fred
372 acl: acl.deny not enabled
372 acl: acl.deny not enabled
373 acl: branch access granted: "ef1ea85a6374" on branch "default"
373 acl: branch access granted: "ef1ea85a6374" on branch "default"
374 acl: path access granted: "ef1ea85a6374"
374 acl: path access granted: "ef1ea85a6374"
375 acl: branch access granted: "f9cafe1212c8" on branch "default"
375 acl: branch access granted: "f9cafe1212c8" on branch "default"
376 acl: path access granted: "f9cafe1212c8"
376 acl: path access granted: "f9cafe1212c8"
377 acl: branch access granted: "911600dab2ae" on branch "default"
377 acl: branch access granted: "911600dab2ae" on branch "default"
378 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
378 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
379 transaction abort!
379 transaction abort!
380 rollback completed
380 rollback completed
381 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
381 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
382 no rollback information available
382 no rollback information available
383 0:6675d58eff77
383 0:6675d58eff77
384
384
385
385
386 Empty [acl.deny]
386 Empty [acl.deny]
387
387
388 $ echo '[acl.deny]' >> $config
388 $ echo '[acl.deny]' >> $config
389 $ do_push barney
389 $ do_push barney
390 Pushing as user barney
390 Pushing as user barney
391 hgrc = """
391 hgrc = """
392 [hooks]
392 [hooks]
393 pretxnchangegroup.acl = python:hgext.acl.hook
393 pretxnchangegroup.acl = python:hgext.acl.hook
394 [acl]
394 [acl]
395 sources = push
395 sources = push
396 [acl.allow]
396 [acl.allow]
397 foo/** = fred
397 foo/** = fred
398 [acl.deny]
398 [acl.deny]
399 """
399 """
400 pushing to ../b
400 pushing to ../b
401 query 1; heads
401 query 1; heads
402 searching for changes
402 searching for changes
403 all remote heads known locally
403 all remote heads known locally
404 3 changesets found
404 3 changesets found
405 list of changesets:
405 list of changesets:
406 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
406 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
407 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
407 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
408 911600dab2ae7a9baff75958b84fe606851ce955
408 911600dab2ae7a9baff75958b84fe606851ce955
409 adding changesets
409 adding changesets
410 bundling: 1/3 changesets (33.33%)
410 bundling: 1/3 changesets (33.33%)
411 bundling: 2/3 changesets (66.67%)
411 bundling: 2/3 changesets (66.67%)
412 bundling: 3/3 changesets (100.00%)
412 bundling: 3/3 changesets (100.00%)
413 bundling: 1/3 manifests (33.33%)
413 bundling: 1/3 manifests (33.33%)
414 bundling: 2/3 manifests (66.67%)
414 bundling: 2/3 manifests (66.67%)
415 bundling: 3/3 manifests (100.00%)
415 bundling: 3/3 manifests (100.00%)
416 bundling: foo/Bar/file.txt 1/3 files (33.33%)
416 bundling: foo/Bar/file.txt 1/3 files (33.33%)
417 bundling: foo/file.txt 2/3 files (66.67%)
417 bundling: foo/file.txt 2/3 files (66.67%)
418 bundling: quux/file.py 3/3 files (100.00%)
418 bundling: quux/file.py 3/3 files (100.00%)
419 changesets: 1 chunks
419 changesets: 1 chunks
420 add changeset ef1ea85a6374
420 add changeset ef1ea85a6374
421 changesets: 2 chunks
421 changesets: 2 chunks
422 add changeset f9cafe1212c8
422 add changeset f9cafe1212c8
423 changesets: 3 chunks
423 changesets: 3 chunks
424 add changeset 911600dab2ae
424 add changeset 911600dab2ae
425 adding manifests
425 adding manifests
426 manifests: 1/3 chunks (33.33%)
426 manifests: 1/3 chunks (33.33%)
427 manifests: 2/3 chunks (66.67%)
427 manifests: 2/3 chunks (66.67%)
428 manifests: 3/3 chunks (100.00%)
428 manifests: 3/3 chunks (100.00%)
429 adding file changes
429 adding file changes
430 adding foo/Bar/file.txt revisions
430 adding foo/Bar/file.txt revisions
431 files: 1/3 chunks (33.33%)
431 files: 1/3 chunks (33.33%)
432 adding foo/file.txt revisions
432 adding foo/file.txt revisions
433 files: 2/3 chunks (66.67%)
433 files: 2/3 chunks (66.67%)
434 adding quux/file.py revisions
434 adding quux/file.py revisions
435 files: 3/3 chunks (100.00%)
435 files: 3/3 chunks (100.00%)
436 added 3 changesets with 3 changes to 3 files
436 added 3 changesets with 3 changes to 3 files
437 calling hook pretxnchangegroup.acl: hgext.acl.hook
437 calling hook pretxnchangegroup.acl: hgext.acl.hook
438 acl: checking access for user "barney"
438 acl: checking access for user "barney"
439 acl: acl.allow.branches not enabled
439 acl: acl.allow.branches not enabled
440 acl: acl.deny.branches not enabled
440 acl: acl.deny.branches not enabled
441 acl: acl.allow enabled, 0 entries for user barney
441 acl: acl.allow enabled, 0 entries for user barney
442 acl: acl.deny enabled, 0 entries for user barney
442 acl: acl.deny enabled, 0 entries for user barney
443 acl: branch access granted: "ef1ea85a6374" on branch "default"
443 acl: branch access granted: "ef1ea85a6374" on branch "default"
444 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
444 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
445 transaction abort!
445 transaction abort!
446 rollback completed
446 rollback completed
447 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
447 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
448 no rollback information available
448 no rollback information available
449 0:6675d58eff77
449 0:6675d58eff77
450
450
451
451
452 fred is allowed inside foo/, but not foo/bar/ (case matters)
452 fred is allowed inside foo/, but not foo/bar/ (case matters)
453
453
454 $ echo 'foo/bar/** = fred' >> $config
454 $ echo 'foo/bar/** = fred' >> $config
455 $ do_push fred
455 $ do_push fred
456 Pushing as user fred
456 Pushing as user fred
457 hgrc = """
457 hgrc = """
458 [hooks]
458 [hooks]
459 pretxnchangegroup.acl = python:hgext.acl.hook
459 pretxnchangegroup.acl = python:hgext.acl.hook
460 [acl]
460 [acl]
461 sources = push
461 sources = push
462 [acl.allow]
462 [acl.allow]
463 foo/** = fred
463 foo/** = fred
464 [acl.deny]
464 [acl.deny]
465 foo/bar/** = fred
465 foo/bar/** = fred
466 """
466 """
467 pushing to ../b
467 pushing to ../b
468 query 1; heads
468 query 1; heads
469 searching for changes
469 searching for changes
470 all remote heads known locally
470 all remote heads known locally
471 3 changesets found
471 3 changesets found
472 list of changesets:
472 list of changesets:
473 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
473 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
474 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
474 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
475 911600dab2ae7a9baff75958b84fe606851ce955
475 911600dab2ae7a9baff75958b84fe606851ce955
476 adding changesets
476 adding changesets
477 bundling: 1/3 changesets (33.33%)
477 bundling: 1/3 changesets (33.33%)
478 bundling: 2/3 changesets (66.67%)
478 bundling: 2/3 changesets (66.67%)
479 bundling: 3/3 changesets (100.00%)
479 bundling: 3/3 changesets (100.00%)
480 bundling: 1/3 manifests (33.33%)
480 bundling: 1/3 manifests (33.33%)
481 bundling: 2/3 manifests (66.67%)
481 bundling: 2/3 manifests (66.67%)
482 bundling: 3/3 manifests (100.00%)
482 bundling: 3/3 manifests (100.00%)
483 bundling: foo/Bar/file.txt 1/3 files (33.33%)
483 bundling: foo/Bar/file.txt 1/3 files (33.33%)
484 bundling: foo/file.txt 2/3 files (66.67%)
484 bundling: foo/file.txt 2/3 files (66.67%)
485 bundling: quux/file.py 3/3 files (100.00%)
485 bundling: quux/file.py 3/3 files (100.00%)
486 changesets: 1 chunks
486 changesets: 1 chunks
487 add changeset ef1ea85a6374
487 add changeset ef1ea85a6374
488 changesets: 2 chunks
488 changesets: 2 chunks
489 add changeset f9cafe1212c8
489 add changeset f9cafe1212c8
490 changesets: 3 chunks
490 changesets: 3 chunks
491 add changeset 911600dab2ae
491 add changeset 911600dab2ae
492 adding manifests
492 adding manifests
493 manifests: 1/3 chunks (33.33%)
493 manifests: 1/3 chunks (33.33%)
494 manifests: 2/3 chunks (66.67%)
494 manifests: 2/3 chunks (66.67%)
495 manifests: 3/3 chunks (100.00%)
495 manifests: 3/3 chunks (100.00%)
496 adding file changes
496 adding file changes
497 adding foo/Bar/file.txt revisions
497 adding foo/Bar/file.txt revisions
498 files: 1/3 chunks (33.33%)
498 files: 1/3 chunks (33.33%)
499 adding foo/file.txt revisions
499 adding foo/file.txt revisions
500 files: 2/3 chunks (66.67%)
500 files: 2/3 chunks (66.67%)
501 adding quux/file.py revisions
501 adding quux/file.py revisions
502 files: 3/3 chunks (100.00%)
502 files: 3/3 chunks (100.00%)
503 added 3 changesets with 3 changes to 3 files
503 added 3 changesets with 3 changes to 3 files
504 calling hook pretxnchangegroup.acl: hgext.acl.hook
504 calling hook pretxnchangegroup.acl: hgext.acl.hook
505 acl: checking access for user "fred"
505 acl: checking access for user "fred"
506 acl: acl.allow.branches not enabled
506 acl: acl.allow.branches not enabled
507 acl: acl.deny.branches not enabled
507 acl: acl.deny.branches not enabled
508 acl: acl.allow enabled, 1 entries for user fred
508 acl: acl.allow enabled, 1 entries for user fred
509 acl: acl.deny enabled, 1 entries for user fred
509 acl: acl.deny enabled, 1 entries for user fred
510 acl: branch access granted: "ef1ea85a6374" on branch "default"
510 acl: branch access granted: "ef1ea85a6374" on branch "default"
511 acl: path access granted: "ef1ea85a6374"
511 acl: path access granted: "ef1ea85a6374"
512 acl: branch access granted: "f9cafe1212c8" on branch "default"
512 acl: branch access granted: "f9cafe1212c8" on branch "default"
513 acl: path access granted: "f9cafe1212c8"
513 acl: path access granted: "f9cafe1212c8"
514 acl: branch access granted: "911600dab2ae" on branch "default"
514 acl: branch access granted: "911600dab2ae" on branch "default"
515 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
515 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
516 transaction abort!
516 transaction abort!
517 rollback completed
517 rollback completed
518 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
518 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
519 no rollback information available
519 no rollback information available
520 0:6675d58eff77
520 0:6675d58eff77
521
521
522
522
523 fred is allowed inside foo/, but not foo/Bar/
523 fred is allowed inside foo/, but not foo/Bar/
524
524
525 $ echo 'foo/Bar/** = fred' >> $config
525 $ echo 'foo/Bar/** = fred' >> $config
526 $ do_push fred
526 $ do_push fred
527 Pushing as user fred
527 Pushing as user fred
528 hgrc = """
528 hgrc = """
529 [hooks]
529 [hooks]
530 pretxnchangegroup.acl = python:hgext.acl.hook
530 pretxnchangegroup.acl = python:hgext.acl.hook
531 [acl]
531 [acl]
532 sources = push
532 sources = push
533 [acl.allow]
533 [acl.allow]
534 foo/** = fred
534 foo/** = fred
535 [acl.deny]
535 [acl.deny]
536 foo/bar/** = fred
536 foo/bar/** = fred
537 foo/Bar/** = fred
537 foo/Bar/** = fred
538 """
538 """
539 pushing to ../b
539 pushing to ../b
540 query 1; heads
540 query 1; heads
541 searching for changes
541 searching for changes
542 all remote heads known locally
542 all remote heads known locally
543 3 changesets found
543 3 changesets found
544 list of changesets:
544 list of changesets:
545 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
545 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
546 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
546 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
547 911600dab2ae7a9baff75958b84fe606851ce955
547 911600dab2ae7a9baff75958b84fe606851ce955
548 adding changesets
548 adding changesets
549 bundling: 1/3 changesets (33.33%)
549 bundling: 1/3 changesets (33.33%)
550 bundling: 2/3 changesets (66.67%)
550 bundling: 2/3 changesets (66.67%)
551 bundling: 3/3 changesets (100.00%)
551 bundling: 3/3 changesets (100.00%)
552 bundling: 1/3 manifests (33.33%)
552 bundling: 1/3 manifests (33.33%)
553 bundling: 2/3 manifests (66.67%)
553 bundling: 2/3 manifests (66.67%)
554 bundling: 3/3 manifests (100.00%)
554 bundling: 3/3 manifests (100.00%)
555 bundling: foo/Bar/file.txt 1/3 files (33.33%)
555 bundling: foo/Bar/file.txt 1/3 files (33.33%)
556 bundling: foo/file.txt 2/3 files (66.67%)
556 bundling: foo/file.txt 2/3 files (66.67%)
557 bundling: quux/file.py 3/3 files (100.00%)
557 bundling: quux/file.py 3/3 files (100.00%)
558 changesets: 1 chunks
558 changesets: 1 chunks
559 add changeset ef1ea85a6374
559 add changeset ef1ea85a6374
560 changesets: 2 chunks
560 changesets: 2 chunks
561 add changeset f9cafe1212c8
561 add changeset f9cafe1212c8
562 changesets: 3 chunks
562 changesets: 3 chunks
563 add changeset 911600dab2ae
563 add changeset 911600dab2ae
564 adding manifests
564 adding manifests
565 manifests: 1/3 chunks (33.33%)
565 manifests: 1/3 chunks (33.33%)
566 manifests: 2/3 chunks (66.67%)
566 manifests: 2/3 chunks (66.67%)
567 manifests: 3/3 chunks (100.00%)
567 manifests: 3/3 chunks (100.00%)
568 adding file changes
568 adding file changes
569 adding foo/Bar/file.txt revisions
569 adding foo/Bar/file.txt revisions
570 files: 1/3 chunks (33.33%)
570 files: 1/3 chunks (33.33%)
571 adding foo/file.txt revisions
571 adding foo/file.txt revisions
572 files: 2/3 chunks (66.67%)
572 files: 2/3 chunks (66.67%)
573 adding quux/file.py revisions
573 adding quux/file.py revisions
574 files: 3/3 chunks (100.00%)
574 files: 3/3 chunks (100.00%)
575 added 3 changesets with 3 changes to 3 files
575 added 3 changesets with 3 changes to 3 files
576 calling hook pretxnchangegroup.acl: hgext.acl.hook
576 calling hook pretxnchangegroup.acl: hgext.acl.hook
577 acl: checking access for user "fred"
577 acl: checking access for user "fred"
578 acl: acl.allow.branches not enabled
578 acl: acl.allow.branches not enabled
579 acl: acl.deny.branches not enabled
579 acl: acl.deny.branches not enabled
580 acl: acl.allow enabled, 1 entries for user fred
580 acl: acl.allow enabled, 1 entries for user fred
581 acl: acl.deny enabled, 2 entries for user fred
581 acl: acl.deny enabled, 2 entries for user fred
582 acl: branch access granted: "ef1ea85a6374" on branch "default"
582 acl: branch access granted: "ef1ea85a6374" on branch "default"
583 acl: path access granted: "ef1ea85a6374"
583 acl: path access granted: "ef1ea85a6374"
584 acl: branch access granted: "f9cafe1212c8" on branch "default"
584 acl: branch access granted: "f9cafe1212c8" on branch "default"
585 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
585 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
586 transaction abort!
586 transaction abort!
587 rollback completed
587 rollback completed
588 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
588 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
589 no rollback information available
589 no rollback information available
590 0:6675d58eff77
590 0:6675d58eff77
591
591
592
592
593 $ echo 'barney is not mentioned => not allowed anywhere'
593 $ echo 'barney is not mentioned => not allowed anywhere'
594 barney is not mentioned => not allowed anywhere
594 barney is not mentioned => not allowed anywhere
595 $ do_push barney
595 $ do_push barney
596 Pushing as user barney
596 Pushing as user barney
597 hgrc = """
597 hgrc = """
598 [hooks]
598 [hooks]
599 pretxnchangegroup.acl = python:hgext.acl.hook
599 pretxnchangegroup.acl = python:hgext.acl.hook
600 [acl]
600 [acl]
601 sources = push
601 sources = push
602 [acl.allow]
602 [acl.allow]
603 foo/** = fred
603 foo/** = fred
604 [acl.deny]
604 [acl.deny]
605 foo/bar/** = fred
605 foo/bar/** = fred
606 foo/Bar/** = fred
606 foo/Bar/** = fred
607 """
607 """
608 pushing to ../b
608 pushing to ../b
609 query 1; heads
609 query 1; heads
610 searching for changes
610 searching for changes
611 all remote heads known locally
611 all remote heads known locally
612 3 changesets found
612 3 changesets found
613 list of changesets:
613 list of changesets:
614 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
614 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
615 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
615 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
616 911600dab2ae7a9baff75958b84fe606851ce955
616 911600dab2ae7a9baff75958b84fe606851ce955
617 adding changesets
617 adding changesets
618 bundling: 1/3 changesets (33.33%)
618 bundling: 1/3 changesets (33.33%)
619 bundling: 2/3 changesets (66.67%)
619 bundling: 2/3 changesets (66.67%)
620 bundling: 3/3 changesets (100.00%)
620 bundling: 3/3 changesets (100.00%)
621 bundling: 1/3 manifests (33.33%)
621 bundling: 1/3 manifests (33.33%)
622 bundling: 2/3 manifests (66.67%)
622 bundling: 2/3 manifests (66.67%)
623 bundling: 3/3 manifests (100.00%)
623 bundling: 3/3 manifests (100.00%)
624 bundling: foo/Bar/file.txt 1/3 files (33.33%)
624 bundling: foo/Bar/file.txt 1/3 files (33.33%)
625 bundling: foo/file.txt 2/3 files (66.67%)
625 bundling: foo/file.txt 2/3 files (66.67%)
626 bundling: quux/file.py 3/3 files (100.00%)
626 bundling: quux/file.py 3/3 files (100.00%)
627 changesets: 1 chunks
627 changesets: 1 chunks
628 add changeset ef1ea85a6374
628 add changeset ef1ea85a6374
629 changesets: 2 chunks
629 changesets: 2 chunks
630 add changeset f9cafe1212c8
630 add changeset f9cafe1212c8
631 changesets: 3 chunks
631 changesets: 3 chunks
632 add changeset 911600dab2ae
632 add changeset 911600dab2ae
633 adding manifests
633 adding manifests
634 manifests: 1/3 chunks (33.33%)
634 manifests: 1/3 chunks (33.33%)
635 manifests: 2/3 chunks (66.67%)
635 manifests: 2/3 chunks (66.67%)
636 manifests: 3/3 chunks (100.00%)
636 manifests: 3/3 chunks (100.00%)
637 adding file changes
637 adding file changes
638 adding foo/Bar/file.txt revisions
638 adding foo/Bar/file.txt revisions
639 files: 1/3 chunks (33.33%)
639 files: 1/3 chunks (33.33%)
640 adding foo/file.txt revisions
640 adding foo/file.txt revisions
641 files: 2/3 chunks (66.67%)
641 files: 2/3 chunks (66.67%)
642 adding quux/file.py revisions
642 adding quux/file.py revisions
643 files: 3/3 chunks (100.00%)
643 files: 3/3 chunks (100.00%)
644 added 3 changesets with 3 changes to 3 files
644 added 3 changesets with 3 changes to 3 files
645 calling hook pretxnchangegroup.acl: hgext.acl.hook
645 calling hook pretxnchangegroup.acl: hgext.acl.hook
646 acl: checking access for user "barney"
646 acl: checking access for user "barney"
647 acl: acl.allow.branches not enabled
647 acl: acl.allow.branches not enabled
648 acl: acl.deny.branches not enabled
648 acl: acl.deny.branches not enabled
649 acl: acl.allow enabled, 0 entries for user barney
649 acl: acl.allow enabled, 0 entries for user barney
650 acl: acl.deny enabled, 0 entries for user barney
650 acl: acl.deny enabled, 0 entries for user barney
651 acl: branch access granted: "ef1ea85a6374" on branch "default"
651 acl: branch access granted: "ef1ea85a6374" on branch "default"
652 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
652 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
653 transaction abort!
653 transaction abort!
654 rollback completed
654 rollback completed
655 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
655 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
656 no rollback information available
656 no rollback information available
657 0:6675d58eff77
657 0:6675d58eff77
658
658
659
659
660 barney is allowed everywhere
660 barney is allowed everywhere
661
661
662 $ echo '[acl.allow]' >> $config
662 $ echo '[acl.allow]' >> $config
663 $ echo '** = barney' >> $config
663 $ echo '** = barney' >> $config
664 $ do_push barney
664 $ do_push barney
665 Pushing as user barney
665 Pushing as user barney
666 hgrc = """
666 hgrc = """
667 [hooks]
667 [hooks]
668 pretxnchangegroup.acl = python:hgext.acl.hook
668 pretxnchangegroup.acl = python:hgext.acl.hook
669 [acl]
669 [acl]
670 sources = push
670 sources = push
671 [acl.allow]
671 [acl.allow]
672 foo/** = fred
672 foo/** = fred
673 [acl.deny]
673 [acl.deny]
674 foo/bar/** = fred
674 foo/bar/** = fred
675 foo/Bar/** = fred
675 foo/Bar/** = fred
676 [acl.allow]
676 [acl.allow]
677 ** = barney
677 ** = barney
678 """
678 """
679 pushing to ../b
679 pushing to ../b
680 query 1; heads
680 query 1; heads
681 searching for changes
681 searching for changes
682 all remote heads known locally
682 all remote heads known locally
683 3 changesets found
683 3 changesets found
684 list of changesets:
684 list of changesets:
685 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
685 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
686 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
686 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
687 911600dab2ae7a9baff75958b84fe606851ce955
687 911600dab2ae7a9baff75958b84fe606851ce955
688 adding changesets
688 adding changesets
689 bundling: 1/3 changesets (33.33%)
689 bundling: 1/3 changesets (33.33%)
690 bundling: 2/3 changesets (66.67%)
690 bundling: 2/3 changesets (66.67%)
691 bundling: 3/3 changesets (100.00%)
691 bundling: 3/3 changesets (100.00%)
692 bundling: 1/3 manifests (33.33%)
692 bundling: 1/3 manifests (33.33%)
693 bundling: 2/3 manifests (66.67%)
693 bundling: 2/3 manifests (66.67%)
694 bundling: 3/3 manifests (100.00%)
694 bundling: 3/3 manifests (100.00%)
695 bundling: foo/Bar/file.txt 1/3 files (33.33%)
695 bundling: foo/Bar/file.txt 1/3 files (33.33%)
696 bundling: foo/file.txt 2/3 files (66.67%)
696 bundling: foo/file.txt 2/3 files (66.67%)
697 bundling: quux/file.py 3/3 files (100.00%)
697 bundling: quux/file.py 3/3 files (100.00%)
698 changesets: 1 chunks
698 changesets: 1 chunks
699 add changeset ef1ea85a6374
699 add changeset ef1ea85a6374
700 changesets: 2 chunks
700 changesets: 2 chunks
701 add changeset f9cafe1212c8
701 add changeset f9cafe1212c8
702 changesets: 3 chunks
702 changesets: 3 chunks
703 add changeset 911600dab2ae
703 add changeset 911600dab2ae
704 adding manifests
704 adding manifests
705 manifests: 1/3 chunks (33.33%)
705 manifests: 1/3 chunks (33.33%)
706 manifests: 2/3 chunks (66.67%)
706 manifests: 2/3 chunks (66.67%)
707 manifests: 3/3 chunks (100.00%)
707 manifests: 3/3 chunks (100.00%)
708 adding file changes
708 adding file changes
709 adding foo/Bar/file.txt revisions
709 adding foo/Bar/file.txt revisions
710 files: 1/3 chunks (33.33%)
710 files: 1/3 chunks (33.33%)
711 adding foo/file.txt revisions
711 adding foo/file.txt revisions
712 files: 2/3 chunks (66.67%)
712 files: 2/3 chunks (66.67%)
713 adding quux/file.py revisions
713 adding quux/file.py revisions
714 files: 3/3 chunks (100.00%)
714 files: 3/3 chunks (100.00%)
715 added 3 changesets with 3 changes to 3 files
715 added 3 changesets with 3 changes to 3 files
716 calling hook pretxnchangegroup.acl: hgext.acl.hook
716 calling hook pretxnchangegroup.acl: hgext.acl.hook
717 acl: checking access for user "barney"
717 acl: checking access for user "barney"
718 acl: acl.allow.branches not enabled
718 acl: acl.allow.branches not enabled
719 acl: acl.deny.branches not enabled
719 acl: acl.deny.branches not enabled
720 acl: acl.allow enabled, 1 entries for user barney
720 acl: acl.allow enabled, 1 entries for user barney
721 acl: acl.deny enabled, 0 entries for user barney
721 acl: acl.deny enabled, 0 entries for user barney
722 acl: branch access granted: "ef1ea85a6374" on branch "default"
722 acl: branch access granted: "ef1ea85a6374" on branch "default"
723 acl: path access granted: "ef1ea85a6374"
723 acl: path access granted: "ef1ea85a6374"
724 acl: branch access granted: "f9cafe1212c8" on branch "default"
724 acl: branch access granted: "f9cafe1212c8" on branch "default"
725 acl: path access granted: "f9cafe1212c8"
725 acl: path access granted: "f9cafe1212c8"
726 acl: branch access granted: "911600dab2ae" on branch "default"
726 acl: branch access granted: "911600dab2ae" on branch "default"
727 acl: path access granted: "911600dab2ae"
727 acl: path access granted: "911600dab2ae"
728 updating the branch cache
728 updating the branch cache
729 checking for updated bookmarks
729 checking for updated bookmarks
730 repository tip rolled back to revision 0 (undo push)
730 repository tip rolled back to revision 0 (undo push)
731 0:6675d58eff77
731 0:6675d58eff77
732
732
733
733
734 wilma can change files with a .txt extension
734 wilma can change files with a .txt extension
735
735
736 $ echo '**/*.txt = wilma' >> $config
736 $ echo '**/*.txt = wilma' >> $config
737 $ do_push wilma
737 $ do_push wilma
738 Pushing as user wilma
738 Pushing as user wilma
739 hgrc = """
739 hgrc = """
740 [hooks]
740 [hooks]
741 pretxnchangegroup.acl = python:hgext.acl.hook
741 pretxnchangegroup.acl = python:hgext.acl.hook
742 [acl]
742 [acl]
743 sources = push
743 sources = push
744 [acl.allow]
744 [acl.allow]
745 foo/** = fred
745 foo/** = fred
746 [acl.deny]
746 [acl.deny]
747 foo/bar/** = fred
747 foo/bar/** = fred
748 foo/Bar/** = fred
748 foo/Bar/** = fred
749 [acl.allow]
749 [acl.allow]
750 ** = barney
750 ** = barney
751 **/*.txt = wilma
751 **/*.txt = wilma
752 """
752 """
753 pushing to ../b
753 pushing to ../b
754 query 1; heads
754 query 1; heads
755 searching for changes
755 searching for changes
756 all remote heads known locally
756 all remote heads known locally
757 invalidating branch cache (tip differs)
757 invalidating branch cache (tip differs)
758 3 changesets found
758 3 changesets found
759 list of changesets:
759 list of changesets:
760 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
760 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
761 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
761 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
762 911600dab2ae7a9baff75958b84fe606851ce955
762 911600dab2ae7a9baff75958b84fe606851ce955
763 adding changesets
763 adding changesets
764 bundling: 1/3 changesets (33.33%)
764 bundling: 1/3 changesets (33.33%)
765 bundling: 2/3 changesets (66.67%)
765 bundling: 2/3 changesets (66.67%)
766 bundling: 3/3 changesets (100.00%)
766 bundling: 3/3 changesets (100.00%)
767 bundling: 1/3 manifests (33.33%)
767 bundling: 1/3 manifests (33.33%)
768 bundling: 2/3 manifests (66.67%)
768 bundling: 2/3 manifests (66.67%)
769 bundling: 3/3 manifests (100.00%)
769 bundling: 3/3 manifests (100.00%)
770 bundling: foo/Bar/file.txt 1/3 files (33.33%)
770 bundling: foo/Bar/file.txt 1/3 files (33.33%)
771 bundling: foo/file.txt 2/3 files (66.67%)
771 bundling: foo/file.txt 2/3 files (66.67%)
772 bundling: quux/file.py 3/3 files (100.00%)
772 bundling: quux/file.py 3/3 files (100.00%)
773 changesets: 1 chunks
773 changesets: 1 chunks
774 add changeset ef1ea85a6374
774 add changeset ef1ea85a6374
775 changesets: 2 chunks
775 changesets: 2 chunks
776 add changeset f9cafe1212c8
776 add changeset f9cafe1212c8
777 changesets: 3 chunks
777 changesets: 3 chunks
778 add changeset 911600dab2ae
778 add changeset 911600dab2ae
779 adding manifests
779 adding manifests
780 manifests: 1/3 chunks (33.33%)
780 manifests: 1/3 chunks (33.33%)
781 manifests: 2/3 chunks (66.67%)
781 manifests: 2/3 chunks (66.67%)
782 manifests: 3/3 chunks (100.00%)
782 manifests: 3/3 chunks (100.00%)
783 adding file changes
783 adding file changes
784 adding foo/Bar/file.txt revisions
784 adding foo/Bar/file.txt revisions
785 files: 1/3 chunks (33.33%)
785 files: 1/3 chunks (33.33%)
786 adding foo/file.txt revisions
786 adding foo/file.txt revisions
787 files: 2/3 chunks (66.67%)
787 files: 2/3 chunks (66.67%)
788 adding quux/file.py revisions
788 adding quux/file.py revisions
789 files: 3/3 chunks (100.00%)
789 files: 3/3 chunks (100.00%)
790 added 3 changesets with 3 changes to 3 files
790 added 3 changesets with 3 changes to 3 files
791 calling hook pretxnchangegroup.acl: hgext.acl.hook
791 calling hook pretxnchangegroup.acl: hgext.acl.hook
792 acl: checking access for user "wilma"
792 acl: checking access for user "wilma"
793 acl: acl.allow.branches not enabled
793 acl: acl.allow.branches not enabled
794 acl: acl.deny.branches not enabled
794 acl: acl.deny.branches not enabled
795 acl: acl.allow enabled, 1 entries for user wilma
795 acl: acl.allow enabled, 1 entries for user wilma
796 acl: acl.deny enabled, 0 entries for user wilma
796 acl: acl.deny enabled, 0 entries for user wilma
797 acl: branch access granted: "ef1ea85a6374" on branch "default"
797 acl: branch access granted: "ef1ea85a6374" on branch "default"
798 acl: path access granted: "ef1ea85a6374"
798 acl: path access granted: "ef1ea85a6374"
799 acl: branch access granted: "f9cafe1212c8" on branch "default"
799 acl: branch access granted: "f9cafe1212c8" on branch "default"
800 acl: path access granted: "f9cafe1212c8"
800 acl: path access granted: "f9cafe1212c8"
801 acl: branch access granted: "911600dab2ae" on branch "default"
801 acl: branch access granted: "911600dab2ae" on branch "default"
802 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
802 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
803 transaction abort!
803 transaction abort!
804 rollback completed
804 rollback completed
805 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
805 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
806 no rollback information available
806 no rollback information available
807 0:6675d58eff77
807 0:6675d58eff77
808
808
809
809
810 file specified by acl.config does not exist
810 file specified by acl.config does not exist
811
811
812 $ echo '[acl]' >> $config
812 $ echo '[acl]' >> $config
813 $ echo 'config = ../acl.config' >> $config
813 $ echo 'config = ../acl.config' >> $config
814 $ do_push barney
814 $ do_push barney
815 Pushing as user barney
815 Pushing as user barney
816 hgrc = """
816 hgrc = """
817 [hooks]
817 [hooks]
818 pretxnchangegroup.acl = python:hgext.acl.hook
818 pretxnchangegroup.acl = python:hgext.acl.hook
819 [acl]
819 [acl]
820 sources = push
820 sources = push
821 [acl.allow]
821 [acl.allow]
822 foo/** = fred
822 foo/** = fred
823 [acl.deny]
823 [acl.deny]
824 foo/bar/** = fred
824 foo/bar/** = fred
825 foo/Bar/** = fred
825 foo/Bar/** = fred
826 [acl.allow]
826 [acl.allow]
827 ** = barney
827 ** = barney
828 **/*.txt = wilma
828 **/*.txt = wilma
829 [acl]
829 [acl]
830 config = ../acl.config
830 config = ../acl.config
831 """
831 """
832 pushing to ../b
832 pushing to ../b
833 query 1; heads
833 query 1; heads
834 searching for changes
834 searching for changes
835 all remote heads known locally
835 all remote heads known locally
836 3 changesets found
836 3 changesets found
837 list of changesets:
837 list of changesets:
838 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
838 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
839 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
839 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
840 911600dab2ae7a9baff75958b84fe606851ce955
840 911600dab2ae7a9baff75958b84fe606851ce955
841 adding changesets
841 adding changesets
842 bundling: 1/3 changesets (33.33%)
842 bundling: 1/3 changesets (33.33%)
843 bundling: 2/3 changesets (66.67%)
843 bundling: 2/3 changesets (66.67%)
844 bundling: 3/3 changesets (100.00%)
844 bundling: 3/3 changesets (100.00%)
845 bundling: 1/3 manifests (33.33%)
845 bundling: 1/3 manifests (33.33%)
846 bundling: 2/3 manifests (66.67%)
846 bundling: 2/3 manifests (66.67%)
847 bundling: 3/3 manifests (100.00%)
847 bundling: 3/3 manifests (100.00%)
848 bundling: foo/Bar/file.txt 1/3 files (33.33%)
848 bundling: foo/Bar/file.txt 1/3 files (33.33%)
849 bundling: foo/file.txt 2/3 files (66.67%)
849 bundling: foo/file.txt 2/3 files (66.67%)
850 bundling: quux/file.py 3/3 files (100.00%)
850 bundling: quux/file.py 3/3 files (100.00%)
851 changesets: 1 chunks
851 changesets: 1 chunks
852 add changeset ef1ea85a6374
852 add changeset ef1ea85a6374
853 changesets: 2 chunks
853 changesets: 2 chunks
854 add changeset f9cafe1212c8
854 add changeset f9cafe1212c8
855 changesets: 3 chunks
855 changesets: 3 chunks
856 add changeset 911600dab2ae
856 add changeset 911600dab2ae
857 adding manifests
857 adding manifests
858 manifests: 1/3 chunks (33.33%)
858 manifests: 1/3 chunks (33.33%)
859 manifests: 2/3 chunks (66.67%)
859 manifests: 2/3 chunks (66.67%)
860 manifests: 3/3 chunks (100.00%)
860 manifests: 3/3 chunks (100.00%)
861 adding file changes
861 adding file changes
862 adding foo/Bar/file.txt revisions
862 adding foo/Bar/file.txt revisions
863 files: 1/3 chunks (33.33%)
863 files: 1/3 chunks (33.33%)
864 adding foo/file.txt revisions
864 adding foo/file.txt revisions
865 files: 2/3 chunks (66.67%)
865 files: 2/3 chunks (66.67%)
866 adding quux/file.py revisions
866 adding quux/file.py revisions
867 files: 3/3 chunks (100.00%)
867 files: 3/3 chunks (100.00%)
868 added 3 changesets with 3 changes to 3 files
868 added 3 changesets with 3 changes to 3 files
869 calling hook pretxnchangegroup.acl: hgext.acl.hook
869 calling hook pretxnchangegroup.acl: hgext.acl.hook
870 acl: checking access for user "barney"
870 acl: checking access for user "barney"
871 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] *: '../acl.config' (glob)
871 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] *: '../acl.config' (glob)
872 transaction abort!
872 transaction abort!
873 rollback completed
873 rollback completed
874 abort: *: ../acl.config (glob)
874 abort: *: ../acl.config (glob)
875 no rollback information available
875 no rollback information available
876 0:6675d58eff77
876 0:6675d58eff77
877
877
878
878
879 betty is allowed inside foo/ by a acl.config file
879 betty is allowed inside foo/ by a acl.config file
880
880
881 $ echo '[acl.allow]' >> acl.config
881 $ echo '[acl.allow]' >> acl.config
882 $ echo 'foo/** = betty' >> acl.config
882 $ echo 'foo/** = betty' >> acl.config
883 $ do_push betty
883 $ do_push betty
884 Pushing as user betty
884 Pushing as user betty
885 hgrc = """
885 hgrc = """
886 [hooks]
886 [hooks]
887 pretxnchangegroup.acl = python:hgext.acl.hook
887 pretxnchangegroup.acl = python:hgext.acl.hook
888 [acl]
888 [acl]
889 sources = push
889 sources = push
890 [acl.allow]
890 [acl.allow]
891 foo/** = fred
891 foo/** = fred
892 [acl.deny]
892 [acl.deny]
893 foo/bar/** = fred
893 foo/bar/** = fred
894 foo/Bar/** = fred
894 foo/Bar/** = fred
895 [acl.allow]
895 [acl.allow]
896 ** = barney
896 ** = barney
897 **/*.txt = wilma
897 **/*.txt = wilma
898 [acl]
898 [acl]
899 config = ../acl.config
899 config = ../acl.config
900 """
900 """
901 acl.config = """
901 acl.config = """
902 [acl.allow]
902 [acl.allow]
903 foo/** = betty
903 foo/** = betty
904 """
904 """
905 pushing to ../b
905 pushing to ../b
906 query 1; heads
906 query 1; heads
907 searching for changes
907 searching for changes
908 all remote heads known locally
908 all remote heads known locally
909 3 changesets found
909 3 changesets found
910 list of changesets:
910 list of changesets:
911 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
911 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
912 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
912 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
913 911600dab2ae7a9baff75958b84fe606851ce955
913 911600dab2ae7a9baff75958b84fe606851ce955
914 adding changesets
914 adding changesets
915 bundling: 1/3 changesets (33.33%)
915 bundling: 1/3 changesets (33.33%)
916 bundling: 2/3 changesets (66.67%)
916 bundling: 2/3 changesets (66.67%)
917 bundling: 3/3 changesets (100.00%)
917 bundling: 3/3 changesets (100.00%)
918 bundling: 1/3 manifests (33.33%)
918 bundling: 1/3 manifests (33.33%)
919 bundling: 2/3 manifests (66.67%)
919 bundling: 2/3 manifests (66.67%)
920 bundling: 3/3 manifests (100.00%)
920 bundling: 3/3 manifests (100.00%)
921 bundling: foo/Bar/file.txt 1/3 files (33.33%)
921 bundling: foo/Bar/file.txt 1/3 files (33.33%)
922 bundling: foo/file.txt 2/3 files (66.67%)
922 bundling: foo/file.txt 2/3 files (66.67%)
923 bundling: quux/file.py 3/3 files (100.00%)
923 bundling: quux/file.py 3/3 files (100.00%)
924 changesets: 1 chunks
924 changesets: 1 chunks
925 add changeset ef1ea85a6374
925 add changeset ef1ea85a6374
926 changesets: 2 chunks
926 changesets: 2 chunks
927 add changeset f9cafe1212c8
927 add changeset f9cafe1212c8
928 changesets: 3 chunks
928 changesets: 3 chunks
929 add changeset 911600dab2ae
929 add changeset 911600dab2ae
930 adding manifests
930 adding manifests
931 manifests: 1/3 chunks (33.33%)
931 manifests: 1/3 chunks (33.33%)
932 manifests: 2/3 chunks (66.67%)
932 manifests: 2/3 chunks (66.67%)
933 manifests: 3/3 chunks (100.00%)
933 manifests: 3/3 chunks (100.00%)
934 adding file changes
934 adding file changes
935 adding foo/Bar/file.txt revisions
935 adding foo/Bar/file.txt revisions
936 files: 1/3 chunks (33.33%)
936 files: 1/3 chunks (33.33%)
937 adding foo/file.txt revisions
937 adding foo/file.txt revisions
938 files: 2/3 chunks (66.67%)
938 files: 2/3 chunks (66.67%)
939 adding quux/file.py revisions
939 adding quux/file.py revisions
940 files: 3/3 chunks (100.00%)
940 files: 3/3 chunks (100.00%)
941 added 3 changesets with 3 changes to 3 files
941 added 3 changesets with 3 changes to 3 files
942 calling hook pretxnchangegroup.acl: hgext.acl.hook
942 calling hook pretxnchangegroup.acl: hgext.acl.hook
943 acl: checking access for user "betty"
943 acl: checking access for user "betty"
944 acl: acl.allow.branches not enabled
944 acl: acl.allow.branches not enabled
945 acl: acl.deny.branches not enabled
945 acl: acl.deny.branches not enabled
946 acl: acl.allow enabled, 1 entries for user betty
946 acl: acl.allow enabled, 1 entries for user betty
947 acl: acl.deny enabled, 0 entries for user betty
947 acl: acl.deny enabled, 0 entries for user betty
948 acl: branch access granted: "ef1ea85a6374" on branch "default"
948 acl: branch access granted: "ef1ea85a6374" on branch "default"
949 acl: path access granted: "ef1ea85a6374"
949 acl: path access granted: "ef1ea85a6374"
950 acl: branch access granted: "f9cafe1212c8" on branch "default"
950 acl: branch access granted: "f9cafe1212c8" on branch "default"
951 acl: path access granted: "f9cafe1212c8"
951 acl: path access granted: "f9cafe1212c8"
952 acl: branch access granted: "911600dab2ae" on branch "default"
952 acl: branch access granted: "911600dab2ae" on branch "default"
953 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
953 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
954 transaction abort!
954 transaction abort!
955 rollback completed
955 rollback completed
956 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
956 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
957 no rollback information available
957 no rollback information available
958 0:6675d58eff77
958 0:6675d58eff77
959
959
960
960
961 acl.config can set only [acl.allow]/[acl.deny]
961 acl.config can set only [acl.allow]/[acl.deny]
962
962
963 $ echo '[hooks]' >> acl.config
963 $ echo '[hooks]' >> acl.config
964 $ echo 'changegroup.acl = false' >> acl.config
964 $ echo 'changegroup.acl = false' >> acl.config
965 $ do_push barney
965 $ do_push barney
966 Pushing as user barney
966 Pushing as user barney
967 hgrc = """
967 hgrc = """
968 [hooks]
968 [hooks]
969 pretxnchangegroup.acl = python:hgext.acl.hook
969 pretxnchangegroup.acl = python:hgext.acl.hook
970 [acl]
970 [acl]
971 sources = push
971 sources = push
972 [acl.allow]
972 [acl.allow]
973 foo/** = fred
973 foo/** = fred
974 [acl.deny]
974 [acl.deny]
975 foo/bar/** = fred
975 foo/bar/** = fred
976 foo/Bar/** = fred
976 foo/Bar/** = fred
977 [acl.allow]
977 [acl.allow]
978 ** = barney
978 ** = barney
979 **/*.txt = wilma
979 **/*.txt = wilma
980 [acl]
980 [acl]
981 config = ../acl.config
981 config = ../acl.config
982 """
982 """
983 acl.config = """
983 acl.config = """
984 [acl.allow]
984 [acl.allow]
985 foo/** = betty
985 foo/** = betty
986 [hooks]
986 [hooks]
987 changegroup.acl = false
987 changegroup.acl = false
988 """
988 """
989 pushing to ../b
989 pushing to ../b
990 query 1; heads
990 query 1; heads
991 searching for changes
991 searching for changes
992 all remote heads known locally
992 all remote heads known locally
993 3 changesets found
993 3 changesets found
994 list of changesets:
994 list of changesets:
995 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
995 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
996 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
996 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
997 911600dab2ae7a9baff75958b84fe606851ce955
997 911600dab2ae7a9baff75958b84fe606851ce955
998 adding changesets
998 adding changesets
999 bundling: 1/3 changesets (33.33%)
999 bundling: 1/3 changesets (33.33%)
1000 bundling: 2/3 changesets (66.67%)
1000 bundling: 2/3 changesets (66.67%)
1001 bundling: 3/3 changesets (100.00%)
1001 bundling: 3/3 changesets (100.00%)
1002 bundling: 1/3 manifests (33.33%)
1002 bundling: 1/3 manifests (33.33%)
1003 bundling: 2/3 manifests (66.67%)
1003 bundling: 2/3 manifests (66.67%)
1004 bundling: 3/3 manifests (100.00%)
1004 bundling: 3/3 manifests (100.00%)
1005 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1005 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1006 bundling: foo/file.txt 2/3 files (66.67%)
1006 bundling: foo/file.txt 2/3 files (66.67%)
1007 bundling: quux/file.py 3/3 files (100.00%)
1007 bundling: quux/file.py 3/3 files (100.00%)
1008 changesets: 1 chunks
1008 changesets: 1 chunks
1009 add changeset ef1ea85a6374
1009 add changeset ef1ea85a6374
1010 changesets: 2 chunks
1010 changesets: 2 chunks
1011 add changeset f9cafe1212c8
1011 add changeset f9cafe1212c8
1012 changesets: 3 chunks
1012 changesets: 3 chunks
1013 add changeset 911600dab2ae
1013 add changeset 911600dab2ae
1014 adding manifests
1014 adding manifests
1015 manifests: 1/3 chunks (33.33%)
1015 manifests: 1/3 chunks (33.33%)
1016 manifests: 2/3 chunks (66.67%)
1016 manifests: 2/3 chunks (66.67%)
1017 manifests: 3/3 chunks (100.00%)
1017 manifests: 3/3 chunks (100.00%)
1018 adding file changes
1018 adding file changes
1019 adding foo/Bar/file.txt revisions
1019 adding foo/Bar/file.txt revisions
1020 files: 1/3 chunks (33.33%)
1020 files: 1/3 chunks (33.33%)
1021 adding foo/file.txt revisions
1021 adding foo/file.txt revisions
1022 files: 2/3 chunks (66.67%)
1022 files: 2/3 chunks (66.67%)
1023 adding quux/file.py revisions
1023 adding quux/file.py revisions
1024 files: 3/3 chunks (100.00%)
1024 files: 3/3 chunks (100.00%)
1025 added 3 changesets with 3 changes to 3 files
1025 added 3 changesets with 3 changes to 3 files
1026 calling hook pretxnchangegroup.acl: hgext.acl.hook
1026 calling hook pretxnchangegroup.acl: hgext.acl.hook
1027 acl: checking access for user "barney"
1027 acl: checking access for user "barney"
1028 acl: acl.allow.branches not enabled
1028 acl: acl.allow.branches not enabled
1029 acl: acl.deny.branches not enabled
1029 acl: acl.deny.branches not enabled
1030 acl: acl.allow enabled, 1 entries for user barney
1030 acl: acl.allow enabled, 1 entries for user barney
1031 acl: acl.deny enabled, 0 entries for user barney
1031 acl: acl.deny enabled, 0 entries for user barney
1032 acl: branch access granted: "ef1ea85a6374" on branch "default"
1032 acl: branch access granted: "ef1ea85a6374" on branch "default"
1033 acl: path access granted: "ef1ea85a6374"
1033 acl: path access granted: "ef1ea85a6374"
1034 acl: branch access granted: "f9cafe1212c8" on branch "default"
1034 acl: branch access granted: "f9cafe1212c8" on branch "default"
1035 acl: path access granted: "f9cafe1212c8"
1035 acl: path access granted: "f9cafe1212c8"
1036 acl: branch access granted: "911600dab2ae" on branch "default"
1036 acl: branch access granted: "911600dab2ae" on branch "default"
1037 acl: path access granted: "911600dab2ae"
1037 acl: path access granted: "911600dab2ae"
1038 updating the branch cache
1038 updating the branch cache
1039 checking for updated bookmarks
1039 checking for updated bookmarks
1040 repository tip rolled back to revision 0 (undo push)
1040 repository tip rolled back to revision 0 (undo push)
1041 0:6675d58eff77
1041 0:6675d58eff77
1042
1042
1043
1043
1044 asterisk
1044 asterisk
1045
1045
1046 $ init_config
1046 $ init_config
1047
1047
1048 asterisk test
1048 asterisk test
1049
1049
1050 $ echo '[acl.allow]' >> $config
1050 $ echo '[acl.allow]' >> $config
1051 $ echo "** = fred" >> $config
1051 $ echo "** = fred" >> $config
1052
1052
1053 fred is always allowed
1053 fred is always allowed
1054
1054
1055 $ do_push fred
1055 $ do_push fred
1056 Pushing as user fred
1056 Pushing as user fred
1057 hgrc = """
1057 hgrc = """
1058 [acl]
1058 [acl]
1059 sources = push
1059 sources = push
1060 [extensions]
1060 [extensions]
1061 [acl.allow]
1061 [acl.allow]
1062 ** = fred
1062 ** = fred
1063 """
1063 """
1064 pushing to ../b
1064 pushing to ../b
1065 query 1; heads
1065 query 1; heads
1066 searching for changes
1066 searching for changes
1067 all remote heads known locally
1067 all remote heads known locally
1068 invalidating branch cache (tip differs)
1068 invalidating branch cache (tip differs)
1069 3 changesets found
1069 3 changesets found
1070 list of changesets:
1070 list of changesets:
1071 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1071 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1072 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1072 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1073 911600dab2ae7a9baff75958b84fe606851ce955
1073 911600dab2ae7a9baff75958b84fe606851ce955
1074 adding changesets
1074 adding changesets
1075 bundling: 1/3 changesets (33.33%)
1075 bundling: 1/3 changesets (33.33%)
1076 bundling: 2/3 changesets (66.67%)
1076 bundling: 2/3 changesets (66.67%)
1077 bundling: 3/3 changesets (100.00%)
1077 bundling: 3/3 changesets (100.00%)
1078 bundling: 1/3 manifests (33.33%)
1078 bundling: 1/3 manifests (33.33%)
1079 bundling: 2/3 manifests (66.67%)
1079 bundling: 2/3 manifests (66.67%)
1080 bundling: 3/3 manifests (100.00%)
1080 bundling: 3/3 manifests (100.00%)
1081 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1081 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1082 bundling: foo/file.txt 2/3 files (66.67%)
1082 bundling: foo/file.txt 2/3 files (66.67%)
1083 bundling: quux/file.py 3/3 files (100.00%)
1083 bundling: quux/file.py 3/3 files (100.00%)
1084 changesets: 1 chunks
1084 changesets: 1 chunks
1085 add changeset ef1ea85a6374
1085 add changeset ef1ea85a6374
1086 changesets: 2 chunks
1086 changesets: 2 chunks
1087 add changeset f9cafe1212c8
1087 add changeset f9cafe1212c8
1088 changesets: 3 chunks
1088 changesets: 3 chunks
1089 add changeset 911600dab2ae
1089 add changeset 911600dab2ae
1090 adding manifests
1090 adding manifests
1091 manifests: 1/3 chunks (33.33%)
1091 manifests: 1/3 chunks (33.33%)
1092 manifests: 2/3 chunks (66.67%)
1092 manifests: 2/3 chunks (66.67%)
1093 manifests: 3/3 chunks (100.00%)
1093 manifests: 3/3 chunks (100.00%)
1094 adding file changes
1094 adding file changes
1095 adding foo/Bar/file.txt revisions
1095 adding foo/Bar/file.txt revisions
1096 files: 1/3 chunks (33.33%)
1096 files: 1/3 chunks (33.33%)
1097 adding foo/file.txt revisions
1097 adding foo/file.txt revisions
1098 files: 2/3 chunks (66.67%)
1098 files: 2/3 chunks (66.67%)
1099 adding quux/file.py revisions
1099 adding quux/file.py revisions
1100 files: 3/3 chunks (100.00%)
1100 files: 3/3 chunks (100.00%)
1101 added 3 changesets with 3 changes to 3 files
1101 added 3 changesets with 3 changes to 3 files
1102 calling hook pretxnchangegroup.acl: hgext.acl.hook
1102 calling hook pretxnchangegroup.acl: hgext.acl.hook
1103 acl: checking access for user "fred"
1103 acl: checking access for user "fred"
1104 acl: acl.allow.branches not enabled
1104 acl: acl.allow.branches not enabled
1105 acl: acl.deny.branches not enabled
1105 acl: acl.deny.branches not enabled
1106 acl: acl.allow enabled, 1 entries for user fred
1106 acl: acl.allow enabled, 1 entries for user fred
1107 acl: acl.deny not enabled
1107 acl: acl.deny not enabled
1108 acl: branch access granted: "ef1ea85a6374" on branch "default"
1108 acl: branch access granted: "ef1ea85a6374" on branch "default"
1109 acl: path access granted: "ef1ea85a6374"
1109 acl: path access granted: "ef1ea85a6374"
1110 acl: branch access granted: "f9cafe1212c8" on branch "default"
1110 acl: branch access granted: "f9cafe1212c8" on branch "default"
1111 acl: path access granted: "f9cafe1212c8"
1111 acl: path access granted: "f9cafe1212c8"
1112 acl: branch access granted: "911600dab2ae" on branch "default"
1112 acl: branch access granted: "911600dab2ae" on branch "default"
1113 acl: path access granted: "911600dab2ae"
1113 acl: path access granted: "911600dab2ae"
1114 updating the branch cache
1114 updating the branch cache
1115 checking for updated bookmarks
1115 checking for updated bookmarks
1116 repository tip rolled back to revision 0 (undo push)
1116 repository tip rolled back to revision 0 (undo push)
1117 0:6675d58eff77
1117 0:6675d58eff77
1118
1118
1119
1119
1120 $ echo '[acl.deny]' >> $config
1120 $ echo '[acl.deny]' >> $config
1121 $ echo "foo/Bar/** = *" >> $config
1121 $ echo "foo/Bar/** = *" >> $config
1122
1122
1123 no one is allowed inside foo/Bar/
1123 no one is allowed inside foo/Bar/
1124
1124
1125 $ do_push fred
1125 $ do_push fred
1126 Pushing as user fred
1126 Pushing as user fred
1127 hgrc = """
1127 hgrc = """
1128 [acl]
1128 [acl]
1129 sources = push
1129 sources = push
1130 [extensions]
1130 [extensions]
1131 [acl.allow]
1131 [acl.allow]
1132 ** = fred
1132 ** = fred
1133 [acl.deny]
1133 [acl.deny]
1134 foo/Bar/** = *
1134 foo/Bar/** = *
1135 """
1135 """
1136 pushing to ../b
1136 pushing to ../b
1137 query 1; heads
1137 query 1; heads
1138 searching for changes
1138 searching for changes
1139 all remote heads known locally
1139 all remote heads known locally
1140 invalidating branch cache (tip differs)
1140 invalidating branch cache (tip differs)
1141 3 changesets found
1141 3 changesets found
1142 list of changesets:
1142 list of changesets:
1143 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1143 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1144 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1144 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1145 911600dab2ae7a9baff75958b84fe606851ce955
1145 911600dab2ae7a9baff75958b84fe606851ce955
1146 adding changesets
1146 adding changesets
1147 bundling: 1/3 changesets (33.33%)
1147 bundling: 1/3 changesets (33.33%)
1148 bundling: 2/3 changesets (66.67%)
1148 bundling: 2/3 changesets (66.67%)
1149 bundling: 3/3 changesets (100.00%)
1149 bundling: 3/3 changesets (100.00%)
1150 bundling: 1/3 manifests (33.33%)
1150 bundling: 1/3 manifests (33.33%)
1151 bundling: 2/3 manifests (66.67%)
1151 bundling: 2/3 manifests (66.67%)
1152 bundling: 3/3 manifests (100.00%)
1152 bundling: 3/3 manifests (100.00%)
1153 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1153 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1154 bundling: foo/file.txt 2/3 files (66.67%)
1154 bundling: foo/file.txt 2/3 files (66.67%)
1155 bundling: quux/file.py 3/3 files (100.00%)
1155 bundling: quux/file.py 3/3 files (100.00%)
1156 changesets: 1 chunks
1156 changesets: 1 chunks
1157 add changeset ef1ea85a6374
1157 add changeset ef1ea85a6374
1158 changesets: 2 chunks
1158 changesets: 2 chunks
1159 add changeset f9cafe1212c8
1159 add changeset f9cafe1212c8
1160 changesets: 3 chunks
1160 changesets: 3 chunks
1161 add changeset 911600dab2ae
1161 add changeset 911600dab2ae
1162 adding manifests
1162 adding manifests
1163 manifests: 1/3 chunks (33.33%)
1163 manifests: 1/3 chunks (33.33%)
1164 manifests: 2/3 chunks (66.67%)
1164 manifests: 2/3 chunks (66.67%)
1165 manifests: 3/3 chunks (100.00%)
1165 manifests: 3/3 chunks (100.00%)
1166 adding file changes
1166 adding file changes
1167 adding foo/Bar/file.txt revisions
1167 adding foo/Bar/file.txt revisions
1168 files: 1/3 chunks (33.33%)
1168 files: 1/3 chunks (33.33%)
1169 adding foo/file.txt revisions
1169 adding foo/file.txt revisions
1170 files: 2/3 chunks (66.67%)
1170 files: 2/3 chunks (66.67%)
1171 adding quux/file.py revisions
1171 adding quux/file.py revisions
1172 files: 3/3 chunks (100.00%)
1172 files: 3/3 chunks (100.00%)
1173 added 3 changesets with 3 changes to 3 files
1173 added 3 changesets with 3 changes to 3 files
1174 calling hook pretxnchangegroup.acl: hgext.acl.hook
1174 calling hook pretxnchangegroup.acl: hgext.acl.hook
1175 acl: checking access for user "fred"
1175 acl: checking access for user "fred"
1176 acl: acl.allow.branches not enabled
1176 acl: acl.allow.branches not enabled
1177 acl: acl.deny.branches not enabled
1177 acl: acl.deny.branches not enabled
1178 acl: acl.allow enabled, 1 entries for user fred
1178 acl: acl.allow enabled, 1 entries for user fred
1179 acl: acl.deny enabled, 1 entries for user fred
1179 acl: acl.deny enabled, 1 entries for user fred
1180 acl: branch access granted: "ef1ea85a6374" on branch "default"
1180 acl: branch access granted: "ef1ea85a6374" on branch "default"
1181 acl: path access granted: "ef1ea85a6374"
1181 acl: path access granted: "ef1ea85a6374"
1182 acl: branch access granted: "f9cafe1212c8" on branch "default"
1182 acl: branch access granted: "f9cafe1212c8" on branch "default"
1183 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1183 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1184 transaction abort!
1184 transaction abort!
1185 rollback completed
1185 rollback completed
1186 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1186 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1187 no rollback information available
1187 no rollback information available
1188 0:6675d58eff77
1188 0:6675d58eff77
1189
1189
1190
1190
1191 Groups
1191 Groups
1192
1192
1193 $ init_config
1193 $ init_config
1194
1194
1195 OS-level groups
1195 OS-level groups
1196
1196
1197 $ echo '[acl.allow]' >> $config
1197 $ echo '[acl.allow]' >> $config
1198 $ echo "** = @group1" >> $config
1198 $ echo "** = @group1" >> $config
1199
1199
1200 @group1 is always allowed
1200 @group1 is always allowed
1201
1201
1202 $ do_push fred
1202 $ do_push fred
1203 Pushing as user fred
1203 Pushing as user fred
1204 hgrc = """
1204 hgrc = """
1205 [acl]
1205 [acl]
1206 sources = push
1206 sources = push
1207 [extensions]
1207 [extensions]
1208 [acl.allow]
1208 [acl.allow]
1209 ** = @group1
1209 ** = @group1
1210 """
1210 """
1211 pushing to ../b
1211 pushing to ../b
1212 query 1; heads
1212 query 1; heads
1213 searching for changes
1213 searching for changes
1214 all remote heads known locally
1214 all remote heads known locally
1215 3 changesets found
1215 3 changesets found
1216 list of changesets:
1216 list of changesets:
1217 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1217 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1218 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1218 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1219 911600dab2ae7a9baff75958b84fe606851ce955
1219 911600dab2ae7a9baff75958b84fe606851ce955
1220 adding changesets
1220 adding changesets
1221 bundling: 1/3 changesets (33.33%)
1221 bundling: 1/3 changesets (33.33%)
1222 bundling: 2/3 changesets (66.67%)
1222 bundling: 2/3 changesets (66.67%)
1223 bundling: 3/3 changesets (100.00%)
1223 bundling: 3/3 changesets (100.00%)
1224 bundling: 1/3 manifests (33.33%)
1224 bundling: 1/3 manifests (33.33%)
1225 bundling: 2/3 manifests (66.67%)
1225 bundling: 2/3 manifests (66.67%)
1226 bundling: 3/3 manifests (100.00%)
1226 bundling: 3/3 manifests (100.00%)
1227 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1227 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1228 bundling: foo/file.txt 2/3 files (66.67%)
1228 bundling: foo/file.txt 2/3 files (66.67%)
1229 bundling: quux/file.py 3/3 files (100.00%)
1229 bundling: quux/file.py 3/3 files (100.00%)
1230 changesets: 1 chunks
1230 changesets: 1 chunks
1231 add changeset ef1ea85a6374
1231 add changeset ef1ea85a6374
1232 changesets: 2 chunks
1232 changesets: 2 chunks
1233 add changeset f9cafe1212c8
1233 add changeset f9cafe1212c8
1234 changesets: 3 chunks
1234 changesets: 3 chunks
1235 add changeset 911600dab2ae
1235 add changeset 911600dab2ae
1236 adding manifests
1236 adding manifests
1237 manifests: 1/3 chunks (33.33%)
1237 manifests: 1/3 chunks (33.33%)
1238 manifests: 2/3 chunks (66.67%)
1238 manifests: 2/3 chunks (66.67%)
1239 manifests: 3/3 chunks (100.00%)
1239 manifests: 3/3 chunks (100.00%)
1240 adding file changes
1240 adding file changes
1241 adding foo/Bar/file.txt revisions
1241 adding foo/Bar/file.txt revisions
1242 files: 1/3 chunks (33.33%)
1242 files: 1/3 chunks (33.33%)
1243 adding foo/file.txt revisions
1243 adding foo/file.txt revisions
1244 files: 2/3 chunks (66.67%)
1244 files: 2/3 chunks (66.67%)
1245 adding quux/file.py revisions
1245 adding quux/file.py revisions
1246 files: 3/3 chunks (100.00%)
1246 files: 3/3 chunks (100.00%)
1247 added 3 changesets with 3 changes to 3 files
1247 added 3 changesets with 3 changes to 3 files
1248 calling hook pretxnchangegroup.acl: hgext.acl.hook
1248 calling hook pretxnchangegroup.acl: hgext.acl.hook
1249 acl: checking access for user "fred"
1249 acl: checking access for user "fred"
1250 acl: acl.allow.branches not enabled
1250 acl: acl.allow.branches not enabled
1251 acl: acl.deny.branches not enabled
1251 acl: acl.deny.branches not enabled
1252 acl: "group1" not defined in [acl.groups]
1252 acl: "group1" not defined in [acl.groups]
1253 acl: acl.allow enabled, 1 entries for user fred
1253 acl: acl.allow enabled, 1 entries for user fred
1254 acl: acl.deny not enabled
1254 acl: acl.deny not enabled
1255 acl: branch access granted: "ef1ea85a6374" on branch "default"
1255 acl: branch access granted: "ef1ea85a6374" on branch "default"
1256 acl: path access granted: "ef1ea85a6374"
1256 acl: path access granted: "ef1ea85a6374"
1257 acl: branch access granted: "f9cafe1212c8" on branch "default"
1257 acl: branch access granted: "f9cafe1212c8" on branch "default"
1258 acl: path access granted: "f9cafe1212c8"
1258 acl: path access granted: "f9cafe1212c8"
1259 acl: branch access granted: "911600dab2ae" on branch "default"
1259 acl: branch access granted: "911600dab2ae" on branch "default"
1260 acl: path access granted: "911600dab2ae"
1260 acl: path access granted: "911600dab2ae"
1261 updating the branch cache
1261 updating the branch cache
1262 checking for updated bookmarks
1262 checking for updated bookmarks
1263 repository tip rolled back to revision 0 (undo push)
1263 repository tip rolled back to revision 0 (undo push)
1264 0:6675d58eff77
1264 0:6675d58eff77
1265
1265
1266
1266
1267 $ echo '[acl.deny]' >> $config
1267 $ echo '[acl.deny]' >> $config
1268 $ echo "foo/Bar/** = @group1" >> $config
1268 $ echo "foo/Bar/** = @group1" >> $config
1269
1269
1270 @group is allowed inside anything but foo/Bar/
1270 @group is allowed inside anything but foo/Bar/
1271
1271
1272 $ do_push fred
1272 $ do_push fred
1273 Pushing as user fred
1273 Pushing as user fred
1274 hgrc = """
1274 hgrc = """
1275 [acl]
1275 [acl]
1276 sources = push
1276 sources = push
1277 [extensions]
1277 [extensions]
1278 [acl.allow]
1278 [acl.allow]
1279 ** = @group1
1279 ** = @group1
1280 [acl.deny]
1280 [acl.deny]
1281 foo/Bar/** = @group1
1281 foo/Bar/** = @group1
1282 """
1282 """
1283 pushing to ../b
1283 pushing to ../b
1284 query 1; heads
1284 query 1; heads
1285 searching for changes
1285 searching for changes
1286 all remote heads known locally
1286 all remote heads known locally
1287 invalidating branch cache (tip differs)
1287 invalidating branch cache (tip differs)
1288 3 changesets found
1288 3 changesets found
1289 list of changesets:
1289 list of changesets:
1290 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1290 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1291 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1291 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1292 911600dab2ae7a9baff75958b84fe606851ce955
1292 911600dab2ae7a9baff75958b84fe606851ce955
1293 adding changesets
1293 adding changesets
1294 bundling: 1/3 changesets (33.33%)
1294 bundling: 1/3 changesets (33.33%)
1295 bundling: 2/3 changesets (66.67%)
1295 bundling: 2/3 changesets (66.67%)
1296 bundling: 3/3 changesets (100.00%)
1296 bundling: 3/3 changesets (100.00%)
1297 bundling: 1/3 manifests (33.33%)
1297 bundling: 1/3 manifests (33.33%)
1298 bundling: 2/3 manifests (66.67%)
1298 bundling: 2/3 manifests (66.67%)
1299 bundling: 3/3 manifests (100.00%)
1299 bundling: 3/3 manifests (100.00%)
1300 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1300 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1301 bundling: foo/file.txt 2/3 files (66.67%)
1301 bundling: foo/file.txt 2/3 files (66.67%)
1302 bundling: quux/file.py 3/3 files (100.00%)
1302 bundling: quux/file.py 3/3 files (100.00%)
1303 changesets: 1 chunks
1303 changesets: 1 chunks
1304 add changeset ef1ea85a6374
1304 add changeset ef1ea85a6374
1305 changesets: 2 chunks
1305 changesets: 2 chunks
1306 add changeset f9cafe1212c8
1306 add changeset f9cafe1212c8
1307 changesets: 3 chunks
1307 changesets: 3 chunks
1308 add changeset 911600dab2ae
1308 add changeset 911600dab2ae
1309 adding manifests
1309 adding manifests
1310 manifests: 1/3 chunks (33.33%)
1310 manifests: 1/3 chunks (33.33%)
1311 manifests: 2/3 chunks (66.67%)
1311 manifests: 2/3 chunks (66.67%)
1312 manifests: 3/3 chunks (100.00%)
1312 manifests: 3/3 chunks (100.00%)
1313 adding file changes
1313 adding file changes
1314 adding foo/Bar/file.txt revisions
1314 adding foo/Bar/file.txt revisions
1315 files: 1/3 chunks (33.33%)
1315 files: 1/3 chunks (33.33%)
1316 adding foo/file.txt revisions
1316 adding foo/file.txt revisions
1317 files: 2/3 chunks (66.67%)
1317 files: 2/3 chunks (66.67%)
1318 adding quux/file.py revisions
1318 adding quux/file.py revisions
1319 files: 3/3 chunks (100.00%)
1319 files: 3/3 chunks (100.00%)
1320 added 3 changesets with 3 changes to 3 files
1320 added 3 changesets with 3 changes to 3 files
1321 calling hook pretxnchangegroup.acl: hgext.acl.hook
1321 calling hook pretxnchangegroup.acl: hgext.acl.hook
1322 acl: checking access for user "fred"
1322 acl: checking access for user "fred"
1323 acl: acl.allow.branches not enabled
1323 acl: acl.allow.branches not enabled
1324 acl: acl.deny.branches not enabled
1324 acl: acl.deny.branches not enabled
1325 acl: "group1" not defined in [acl.groups]
1325 acl: "group1" not defined in [acl.groups]
1326 acl: acl.allow enabled, 1 entries for user fred
1326 acl: acl.allow enabled, 1 entries for user fred
1327 acl: "group1" not defined in [acl.groups]
1327 acl: "group1" not defined in [acl.groups]
1328 acl: acl.deny enabled, 1 entries for user fred
1328 acl: acl.deny enabled, 1 entries for user fred
1329 acl: branch access granted: "ef1ea85a6374" on branch "default"
1329 acl: branch access granted: "ef1ea85a6374" on branch "default"
1330 acl: path access granted: "ef1ea85a6374"
1330 acl: path access granted: "ef1ea85a6374"
1331 acl: branch access granted: "f9cafe1212c8" on branch "default"
1331 acl: branch access granted: "f9cafe1212c8" on branch "default"
1332 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1332 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1333 transaction abort!
1333 transaction abort!
1334 rollback completed
1334 rollback completed
1335 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1335 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1336 no rollback information available
1336 no rollback information available
1337 0:6675d58eff77
1337 0:6675d58eff77
1338
1338
1339
1339
1340 Invalid group
1340 Invalid group
1341
1341
1342 Disable the fakegroups trick to get real failures
1342 Disable the fakegroups trick to get real failures
1343
1343
1344 $ grep -v fakegroups $config > config.tmp
1344 $ grep -v fakegroups $config > config.tmp
1345 $ mv config.tmp $config
1345 $ mv config.tmp $config
1346 $ echo '[acl.allow]' >> $config
1346 $ echo '[acl.allow]' >> $config
1347 $ echo "** = @unlikelytoexist" >> $config
1347 $ echo "** = @unlikelytoexist" >> $config
1348 $ do_push fred 2>&1 | grep unlikelytoexist
1348 $ do_push fred 2>&1 | grep unlikelytoexist
1349 ** = @unlikelytoexist
1349 ** = @unlikelytoexist
1350 acl: "unlikelytoexist" not defined in [acl.groups]
1350 acl: "unlikelytoexist" not defined in [acl.groups]
1351 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1351 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1352 abort: group 'unlikelytoexist' is undefined
1352 abort: group 'unlikelytoexist' is undefined
1353
1353
1354
1354
1355 Branch acl tests setup
1355 Branch acl tests setup
1356
1356
1357 $ init_config
1357 $ init_config
1358 $ cd b
1358 $ cd b
1359 $ hg up
1359 $ hg up
1360 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1360 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1361 $ hg branch foobar
1361 $ hg branch foobar
1362 marked working directory as branch foobar
1362 marked working directory as branch foobar
1363 (branches are permanent and global, did you want a bookmark?)
1363 $ hg commit -m 'create foobar'
1364 $ hg commit -m 'create foobar'
1364 $ echo 'foo contents' > abc.txt
1365 $ echo 'foo contents' > abc.txt
1365 $ hg add abc.txt
1366 $ hg add abc.txt
1366 $ hg commit -m 'foobar contents'
1367 $ hg commit -m 'foobar contents'
1367 $ cd ..
1368 $ cd ..
1368 $ hg --cwd a pull ../b
1369 $ hg --cwd a pull ../b
1369 pulling from ../b
1370 pulling from ../b
1370 searching for changes
1371 searching for changes
1371 adding changesets
1372 adding changesets
1372 adding manifests
1373 adding manifests
1373 adding file changes
1374 adding file changes
1374 added 2 changesets with 1 changes to 1 files (+1 heads)
1375 added 2 changesets with 1 changes to 1 files (+1 heads)
1375 (run 'hg heads' to see heads)
1376 (run 'hg heads' to see heads)
1376
1377
1377 Create additional changeset on foobar branch
1378 Create additional changeset on foobar branch
1378
1379
1379 $ cd a
1380 $ cd a
1380 $ hg up -C foobar
1381 $ hg up -C foobar
1381 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1382 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1382 $ echo 'foo contents2' > abc.txt
1383 $ echo 'foo contents2' > abc.txt
1383 $ hg commit -m 'foobar contents2'
1384 $ hg commit -m 'foobar contents2'
1384 $ cd ..
1385 $ cd ..
1385
1386
1386
1387
1387 No branch acls specified
1388 No branch acls specified
1388
1389
1389 $ do_push astro
1390 $ do_push astro
1390 Pushing as user astro
1391 Pushing as user astro
1391 hgrc = """
1392 hgrc = """
1392 [acl]
1393 [acl]
1393 sources = push
1394 sources = push
1394 [extensions]
1395 [extensions]
1395 """
1396 """
1396 pushing to ../b
1397 pushing to ../b
1397 query 1; heads
1398 query 1; heads
1398 searching for changes
1399 searching for changes
1399 all remote heads known locally
1400 all remote heads known locally
1400 4 changesets found
1401 4 changesets found
1401 list of changesets:
1402 list of changesets:
1402 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1403 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1403 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1404 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1404 911600dab2ae7a9baff75958b84fe606851ce955
1405 911600dab2ae7a9baff75958b84fe606851ce955
1405 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1406 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1406 adding changesets
1407 adding changesets
1407 bundling: 1/4 changesets (25.00%)
1408 bundling: 1/4 changesets (25.00%)
1408 bundling: 2/4 changesets (50.00%)
1409 bundling: 2/4 changesets (50.00%)
1409 bundling: 3/4 changesets (75.00%)
1410 bundling: 3/4 changesets (75.00%)
1410 bundling: 4/4 changesets (100.00%)
1411 bundling: 4/4 changesets (100.00%)
1411 bundling: 1/4 manifests (25.00%)
1412 bundling: 1/4 manifests (25.00%)
1412 bundling: 2/4 manifests (50.00%)
1413 bundling: 2/4 manifests (50.00%)
1413 bundling: 3/4 manifests (75.00%)
1414 bundling: 3/4 manifests (75.00%)
1414 bundling: 4/4 manifests (100.00%)
1415 bundling: 4/4 manifests (100.00%)
1415 bundling: abc.txt 1/4 files (25.00%)
1416 bundling: abc.txt 1/4 files (25.00%)
1416 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1417 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1417 bundling: foo/file.txt 3/4 files (75.00%)
1418 bundling: foo/file.txt 3/4 files (75.00%)
1418 bundling: quux/file.py 4/4 files (100.00%)
1419 bundling: quux/file.py 4/4 files (100.00%)
1419 changesets: 1 chunks
1420 changesets: 1 chunks
1420 add changeset ef1ea85a6374
1421 add changeset ef1ea85a6374
1421 changesets: 2 chunks
1422 changesets: 2 chunks
1422 add changeset f9cafe1212c8
1423 add changeset f9cafe1212c8
1423 changesets: 3 chunks
1424 changesets: 3 chunks
1424 add changeset 911600dab2ae
1425 add changeset 911600dab2ae
1425 changesets: 4 chunks
1426 changesets: 4 chunks
1426 add changeset e8fc755d4d82
1427 add changeset e8fc755d4d82
1427 adding manifests
1428 adding manifests
1428 manifests: 1/4 chunks (25.00%)
1429 manifests: 1/4 chunks (25.00%)
1429 manifests: 2/4 chunks (50.00%)
1430 manifests: 2/4 chunks (50.00%)
1430 manifests: 3/4 chunks (75.00%)
1431 manifests: 3/4 chunks (75.00%)
1431 manifests: 4/4 chunks (100.00%)
1432 manifests: 4/4 chunks (100.00%)
1432 adding file changes
1433 adding file changes
1433 adding abc.txt revisions
1434 adding abc.txt revisions
1434 files: 1/4 chunks (25.00%)
1435 files: 1/4 chunks (25.00%)
1435 adding foo/Bar/file.txt revisions
1436 adding foo/Bar/file.txt revisions
1436 files: 2/4 chunks (50.00%)
1437 files: 2/4 chunks (50.00%)
1437 adding foo/file.txt revisions
1438 adding foo/file.txt revisions
1438 files: 3/4 chunks (75.00%)
1439 files: 3/4 chunks (75.00%)
1439 adding quux/file.py revisions
1440 adding quux/file.py revisions
1440 files: 4/4 chunks (100.00%)
1441 files: 4/4 chunks (100.00%)
1441 added 4 changesets with 4 changes to 4 files (+1 heads)
1442 added 4 changesets with 4 changes to 4 files (+1 heads)
1442 calling hook pretxnchangegroup.acl: hgext.acl.hook
1443 calling hook pretxnchangegroup.acl: hgext.acl.hook
1443 acl: checking access for user "astro"
1444 acl: checking access for user "astro"
1444 acl: acl.allow.branches not enabled
1445 acl: acl.allow.branches not enabled
1445 acl: acl.deny.branches not enabled
1446 acl: acl.deny.branches not enabled
1446 acl: acl.allow not enabled
1447 acl: acl.allow not enabled
1447 acl: acl.deny not enabled
1448 acl: acl.deny not enabled
1448 acl: branch access granted: "ef1ea85a6374" on branch "default"
1449 acl: branch access granted: "ef1ea85a6374" on branch "default"
1449 acl: path access granted: "ef1ea85a6374"
1450 acl: path access granted: "ef1ea85a6374"
1450 acl: branch access granted: "f9cafe1212c8" on branch "default"
1451 acl: branch access granted: "f9cafe1212c8" on branch "default"
1451 acl: path access granted: "f9cafe1212c8"
1452 acl: path access granted: "f9cafe1212c8"
1452 acl: branch access granted: "911600dab2ae" on branch "default"
1453 acl: branch access granted: "911600dab2ae" on branch "default"
1453 acl: path access granted: "911600dab2ae"
1454 acl: path access granted: "911600dab2ae"
1454 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1455 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1455 acl: path access granted: "e8fc755d4d82"
1456 acl: path access granted: "e8fc755d4d82"
1456 updating the branch cache
1457 updating the branch cache
1457 checking for updated bookmarks
1458 checking for updated bookmarks
1458 repository tip rolled back to revision 2 (undo push)
1459 repository tip rolled back to revision 2 (undo push)
1459 2:fb35475503ef
1460 2:fb35475503ef
1460
1461
1461
1462
1462 Branch acl deny test
1463 Branch acl deny test
1463
1464
1464 $ echo "[acl.deny.branches]" >> $config
1465 $ echo "[acl.deny.branches]" >> $config
1465 $ echo "foobar = *" >> $config
1466 $ echo "foobar = *" >> $config
1466 $ do_push astro
1467 $ do_push astro
1467 Pushing as user astro
1468 Pushing as user astro
1468 hgrc = """
1469 hgrc = """
1469 [acl]
1470 [acl]
1470 sources = push
1471 sources = push
1471 [extensions]
1472 [extensions]
1472 [acl.deny.branches]
1473 [acl.deny.branches]
1473 foobar = *
1474 foobar = *
1474 """
1475 """
1475 pushing to ../b
1476 pushing to ../b
1476 query 1; heads
1477 query 1; heads
1477 searching for changes
1478 searching for changes
1478 all remote heads known locally
1479 all remote heads known locally
1479 invalidating branch cache (tip differs)
1480 invalidating branch cache (tip differs)
1480 4 changesets found
1481 4 changesets found
1481 list of changesets:
1482 list of changesets:
1482 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1483 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1483 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1484 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1484 911600dab2ae7a9baff75958b84fe606851ce955
1485 911600dab2ae7a9baff75958b84fe606851ce955
1485 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1486 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1486 adding changesets
1487 adding changesets
1487 bundling: 1/4 changesets (25.00%)
1488 bundling: 1/4 changesets (25.00%)
1488 bundling: 2/4 changesets (50.00%)
1489 bundling: 2/4 changesets (50.00%)
1489 bundling: 3/4 changesets (75.00%)
1490 bundling: 3/4 changesets (75.00%)
1490 bundling: 4/4 changesets (100.00%)
1491 bundling: 4/4 changesets (100.00%)
1491 bundling: 1/4 manifests (25.00%)
1492 bundling: 1/4 manifests (25.00%)
1492 bundling: 2/4 manifests (50.00%)
1493 bundling: 2/4 manifests (50.00%)
1493 bundling: 3/4 manifests (75.00%)
1494 bundling: 3/4 manifests (75.00%)
1494 bundling: 4/4 manifests (100.00%)
1495 bundling: 4/4 manifests (100.00%)
1495 bundling: abc.txt 1/4 files (25.00%)
1496 bundling: abc.txt 1/4 files (25.00%)
1496 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1497 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1497 bundling: foo/file.txt 3/4 files (75.00%)
1498 bundling: foo/file.txt 3/4 files (75.00%)
1498 bundling: quux/file.py 4/4 files (100.00%)
1499 bundling: quux/file.py 4/4 files (100.00%)
1499 changesets: 1 chunks
1500 changesets: 1 chunks
1500 add changeset ef1ea85a6374
1501 add changeset ef1ea85a6374
1501 changesets: 2 chunks
1502 changesets: 2 chunks
1502 add changeset f9cafe1212c8
1503 add changeset f9cafe1212c8
1503 changesets: 3 chunks
1504 changesets: 3 chunks
1504 add changeset 911600dab2ae
1505 add changeset 911600dab2ae
1505 changesets: 4 chunks
1506 changesets: 4 chunks
1506 add changeset e8fc755d4d82
1507 add changeset e8fc755d4d82
1507 adding manifests
1508 adding manifests
1508 manifests: 1/4 chunks (25.00%)
1509 manifests: 1/4 chunks (25.00%)
1509 manifests: 2/4 chunks (50.00%)
1510 manifests: 2/4 chunks (50.00%)
1510 manifests: 3/4 chunks (75.00%)
1511 manifests: 3/4 chunks (75.00%)
1511 manifests: 4/4 chunks (100.00%)
1512 manifests: 4/4 chunks (100.00%)
1512 adding file changes
1513 adding file changes
1513 adding abc.txt revisions
1514 adding abc.txt revisions
1514 files: 1/4 chunks (25.00%)
1515 files: 1/4 chunks (25.00%)
1515 adding foo/Bar/file.txt revisions
1516 adding foo/Bar/file.txt revisions
1516 files: 2/4 chunks (50.00%)
1517 files: 2/4 chunks (50.00%)
1517 adding foo/file.txt revisions
1518 adding foo/file.txt revisions
1518 files: 3/4 chunks (75.00%)
1519 files: 3/4 chunks (75.00%)
1519 adding quux/file.py revisions
1520 adding quux/file.py revisions
1520 files: 4/4 chunks (100.00%)
1521 files: 4/4 chunks (100.00%)
1521 added 4 changesets with 4 changes to 4 files (+1 heads)
1522 added 4 changesets with 4 changes to 4 files (+1 heads)
1522 calling hook pretxnchangegroup.acl: hgext.acl.hook
1523 calling hook pretxnchangegroup.acl: hgext.acl.hook
1523 acl: checking access for user "astro"
1524 acl: checking access for user "astro"
1524 acl: acl.allow.branches not enabled
1525 acl: acl.allow.branches not enabled
1525 acl: acl.deny.branches enabled, 1 entries for user astro
1526 acl: acl.deny.branches enabled, 1 entries for user astro
1526 acl: acl.allow not enabled
1527 acl: acl.allow not enabled
1527 acl: acl.deny not enabled
1528 acl: acl.deny not enabled
1528 acl: branch access granted: "ef1ea85a6374" on branch "default"
1529 acl: branch access granted: "ef1ea85a6374" on branch "default"
1529 acl: path access granted: "ef1ea85a6374"
1530 acl: path access granted: "ef1ea85a6374"
1530 acl: branch access granted: "f9cafe1212c8" on branch "default"
1531 acl: branch access granted: "f9cafe1212c8" on branch "default"
1531 acl: path access granted: "f9cafe1212c8"
1532 acl: path access granted: "f9cafe1212c8"
1532 acl: branch access granted: "911600dab2ae" on branch "default"
1533 acl: branch access granted: "911600dab2ae" on branch "default"
1533 acl: path access granted: "911600dab2ae"
1534 acl: path access granted: "911600dab2ae"
1534 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1535 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1535 transaction abort!
1536 transaction abort!
1536 rollback completed
1537 rollback completed
1537 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1538 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1538 no rollback information available
1539 no rollback information available
1539 2:fb35475503ef
1540 2:fb35475503ef
1540
1541
1541
1542
1542 Branch acl empty allow test
1543 Branch acl empty allow test
1543
1544
1544 $ init_config
1545 $ init_config
1545 $ echo "[acl.allow.branches]" >> $config
1546 $ echo "[acl.allow.branches]" >> $config
1546 $ do_push astro
1547 $ do_push astro
1547 Pushing as user astro
1548 Pushing as user astro
1548 hgrc = """
1549 hgrc = """
1549 [acl]
1550 [acl]
1550 sources = push
1551 sources = push
1551 [extensions]
1552 [extensions]
1552 [acl.allow.branches]
1553 [acl.allow.branches]
1553 """
1554 """
1554 pushing to ../b
1555 pushing to ../b
1555 query 1; heads
1556 query 1; heads
1556 searching for changes
1557 searching for changes
1557 all remote heads known locally
1558 all remote heads known locally
1558 4 changesets found
1559 4 changesets found
1559 list of changesets:
1560 list of changesets:
1560 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1561 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1561 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1562 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1562 911600dab2ae7a9baff75958b84fe606851ce955
1563 911600dab2ae7a9baff75958b84fe606851ce955
1563 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1564 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1564 adding changesets
1565 adding changesets
1565 bundling: 1/4 changesets (25.00%)
1566 bundling: 1/4 changesets (25.00%)
1566 bundling: 2/4 changesets (50.00%)
1567 bundling: 2/4 changesets (50.00%)
1567 bundling: 3/4 changesets (75.00%)
1568 bundling: 3/4 changesets (75.00%)
1568 bundling: 4/4 changesets (100.00%)
1569 bundling: 4/4 changesets (100.00%)
1569 bundling: 1/4 manifests (25.00%)
1570 bundling: 1/4 manifests (25.00%)
1570 bundling: 2/4 manifests (50.00%)
1571 bundling: 2/4 manifests (50.00%)
1571 bundling: 3/4 manifests (75.00%)
1572 bundling: 3/4 manifests (75.00%)
1572 bundling: 4/4 manifests (100.00%)
1573 bundling: 4/4 manifests (100.00%)
1573 bundling: abc.txt 1/4 files (25.00%)
1574 bundling: abc.txt 1/4 files (25.00%)
1574 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1575 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1575 bundling: foo/file.txt 3/4 files (75.00%)
1576 bundling: foo/file.txt 3/4 files (75.00%)
1576 bundling: quux/file.py 4/4 files (100.00%)
1577 bundling: quux/file.py 4/4 files (100.00%)
1577 changesets: 1 chunks
1578 changesets: 1 chunks
1578 add changeset ef1ea85a6374
1579 add changeset ef1ea85a6374
1579 changesets: 2 chunks
1580 changesets: 2 chunks
1580 add changeset f9cafe1212c8
1581 add changeset f9cafe1212c8
1581 changesets: 3 chunks
1582 changesets: 3 chunks
1582 add changeset 911600dab2ae
1583 add changeset 911600dab2ae
1583 changesets: 4 chunks
1584 changesets: 4 chunks
1584 add changeset e8fc755d4d82
1585 add changeset e8fc755d4d82
1585 adding manifests
1586 adding manifests
1586 manifests: 1/4 chunks (25.00%)
1587 manifests: 1/4 chunks (25.00%)
1587 manifests: 2/4 chunks (50.00%)
1588 manifests: 2/4 chunks (50.00%)
1588 manifests: 3/4 chunks (75.00%)
1589 manifests: 3/4 chunks (75.00%)
1589 manifests: 4/4 chunks (100.00%)
1590 manifests: 4/4 chunks (100.00%)
1590 adding file changes
1591 adding file changes
1591 adding abc.txt revisions
1592 adding abc.txt revisions
1592 files: 1/4 chunks (25.00%)
1593 files: 1/4 chunks (25.00%)
1593 adding foo/Bar/file.txt revisions
1594 adding foo/Bar/file.txt revisions
1594 files: 2/4 chunks (50.00%)
1595 files: 2/4 chunks (50.00%)
1595 adding foo/file.txt revisions
1596 adding foo/file.txt revisions
1596 files: 3/4 chunks (75.00%)
1597 files: 3/4 chunks (75.00%)
1597 adding quux/file.py revisions
1598 adding quux/file.py revisions
1598 files: 4/4 chunks (100.00%)
1599 files: 4/4 chunks (100.00%)
1599 added 4 changesets with 4 changes to 4 files (+1 heads)
1600 added 4 changesets with 4 changes to 4 files (+1 heads)
1600 calling hook pretxnchangegroup.acl: hgext.acl.hook
1601 calling hook pretxnchangegroup.acl: hgext.acl.hook
1601 acl: checking access for user "astro"
1602 acl: checking access for user "astro"
1602 acl: acl.allow.branches enabled, 0 entries for user astro
1603 acl: acl.allow.branches enabled, 0 entries for user astro
1603 acl: acl.deny.branches not enabled
1604 acl: acl.deny.branches not enabled
1604 acl: acl.allow not enabled
1605 acl: acl.allow not enabled
1605 acl: acl.deny not enabled
1606 acl: acl.deny not enabled
1606 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1607 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1607 transaction abort!
1608 transaction abort!
1608 rollback completed
1609 rollback completed
1609 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1610 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1610 no rollback information available
1611 no rollback information available
1611 2:fb35475503ef
1612 2:fb35475503ef
1612
1613
1613
1614
1614 Branch acl allow other
1615 Branch acl allow other
1615
1616
1616 $ init_config
1617 $ init_config
1617 $ echo "[acl.allow.branches]" >> $config
1618 $ echo "[acl.allow.branches]" >> $config
1618 $ echo "* = george" >> $config
1619 $ echo "* = george" >> $config
1619 $ do_push astro
1620 $ do_push astro
1620 Pushing as user astro
1621 Pushing as user astro
1621 hgrc = """
1622 hgrc = """
1622 [acl]
1623 [acl]
1623 sources = push
1624 sources = push
1624 [extensions]
1625 [extensions]
1625 [acl.allow.branches]
1626 [acl.allow.branches]
1626 * = george
1627 * = george
1627 """
1628 """
1628 pushing to ../b
1629 pushing to ../b
1629 query 1; heads
1630 query 1; heads
1630 searching for changes
1631 searching for changes
1631 all remote heads known locally
1632 all remote heads known locally
1632 4 changesets found
1633 4 changesets found
1633 list of changesets:
1634 list of changesets:
1634 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1635 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1635 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1636 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1636 911600dab2ae7a9baff75958b84fe606851ce955
1637 911600dab2ae7a9baff75958b84fe606851ce955
1637 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1638 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1638 adding changesets
1639 adding changesets
1639 bundling: 1/4 changesets (25.00%)
1640 bundling: 1/4 changesets (25.00%)
1640 bundling: 2/4 changesets (50.00%)
1641 bundling: 2/4 changesets (50.00%)
1641 bundling: 3/4 changesets (75.00%)
1642 bundling: 3/4 changesets (75.00%)
1642 bundling: 4/4 changesets (100.00%)
1643 bundling: 4/4 changesets (100.00%)
1643 bundling: 1/4 manifests (25.00%)
1644 bundling: 1/4 manifests (25.00%)
1644 bundling: 2/4 manifests (50.00%)
1645 bundling: 2/4 manifests (50.00%)
1645 bundling: 3/4 manifests (75.00%)
1646 bundling: 3/4 manifests (75.00%)
1646 bundling: 4/4 manifests (100.00%)
1647 bundling: 4/4 manifests (100.00%)
1647 bundling: abc.txt 1/4 files (25.00%)
1648 bundling: abc.txt 1/4 files (25.00%)
1648 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1649 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1649 bundling: foo/file.txt 3/4 files (75.00%)
1650 bundling: foo/file.txt 3/4 files (75.00%)
1650 bundling: quux/file.py 4/4 files (100.00%)
1651 bundling: quux/file.py 4/4 files (100.00%)
1651 changesets: 1 chunks
1652 changesets: 1 chunks
1652 add changeset ef1ea85a6374
1653 add changeset ef1ea85a6374
1653 changesets: 2 chunks
1654 changesets: 2 chunks
1654 add changeset f9cafe1212c8
1655 add changeset f9cafe1212c8
1655 changesets: 3 chunks
1656 changesets: 3 chunks
1656 add changeset 911600dab2ae
1657 add changeset 911600dab2ae
1657 changesets: 4 chunks
1658 changesets: 4 chunks
1658 add changeset e8fc755d4d82
1659 add changeset e8fc755d4d82
1659 adding manifests
1660 adding manifests
1660 manifests: 1/4 chunks (25.00%)
1661 manifests: 1/4 chunks (25.00%)
1661 manifests: 2/4 chunks (50.00%)
1662 manifests: 2/4 chunks (50.00%)
1662 manifests: 3/4 chunks (75.00%)
1663 manifests: 3/4 chunks (75.00%)
1663 manifests: 4/4 chunks (100.00%)
1664 manifests: 4/4 chunks (100.00%)
1664 adding file changes
1665 adding file changes
1665 adding abc.txt revisions
1666 adding abc.txt revisions
1666 files: 1/4 chunks (25.00%)
1667 files: 1/4 chunks (25.00%)
1667 adding foo/Bar/file.txt revisions
1668 adding foo/Bar/file.txt revisions
1668 files: 2/4 chunks (50.00%)
1669 files: 2/4 chunks (50.00%)
1669 adding foo/file.txt revisions
1670 adding foo/file.txt revisions
1670 files: 3/4 chunks (75.00%)
1671 files: 3/4 chunks (75.00%)
1671 adding quux/file.py revisions
1672 adding quux/file.py revisions
1672 files: 4/4 chunks (100.00%)
1673 files: 4/4 chunks (100.00%)
1673 added 4 changesets with 4 changes to 4 files (+1 heads)
1674 added 4 changesets with 4 changes to 4 files (+1 heads)
1674 calling hook pretxnchangegroup.acl: hgext.acl.hook
1675 calling hook pretxnchangegroup.acl: hgext.acl.hook
1675 acl: checking access for user "astro"
1676 acl: checking access for user "astro"
1676 acl: acl.allow.branches enabled, 0 entries for user astro
1677 acl: acl.allow.branches enabled, 0 entries for user astro
1677 acl: acl.deny.branches not enabled
1678 acl: acl.deny.branches not enabled
1678 acl: acl.allow not enabled
1679 acl: acl.allow not enabled
1679 acl: acl.deny not enabled
1680 acl: acl.deny not enabled
1680 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1681 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1681 transaction abort!
1682 transaction abort!
1682 rollback completed
1683 rollback completed
1683 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1684 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1684 no rollback information available
1685 no rollback information available
1685 2:fb35475503ef
1686 2:fb35475503ef
1686
1687
1687 $ do_push george
1688 $ do_push george
1688 Pushing as user george
1689 Pushing as user george
1689 hgrc = """
1690 hgrc = """
1690 [acl]
1691 [acl]
1691 sources = push
1692 sources = push
1692 [extensions]
1693 [extensions]
1693 [acl.allow.branches]
1694 [acl.allow.branches]
1694 * = george
1695 * = george
1695 """
1696 """
1696 pushing to ../b
1697 pushing to ../b
1697 query 1; heads
1698 query 1; heads
1698 searching for changes
1699 searching for changes
1699 all remote heads known locally
1700 all remote heads known locally
1700 4 changesets found
1701 4 changesets found
1701 list of changesets:
1702 list of changesets:
1702 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1703 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1703 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1704 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1704 911600dab2ae7a9baff75958b84fe606851ce955
1705 911600dab2ae7a9baff75958b84fe606851ce955
1705 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1706 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1706 adding changesets
1707 adding changesets
1707 bundling: 1/4 changesets (25.00%)
1708 bundling: 1/4 changesets (25.00%)
1708 bundling: 2/4 changesets (50.00%)
1709 bundling: 2/4 changesets (50.00%)
1709 bundling: 3/4 changesets (75.00%)
1710 bundling: 3/4 changesets (75.00%)
1710 bundling: 4/4 changesets (100.00%)
1711 bundling: 4/4 changesets (100.00%)
1711 bundling: 1/4 manifests (25.00%)
1712 bundling: 1/4 manifests (25.00%)
1712 bundling: 2/4 manifests (50.00%)
1713 bundling: 2/4 manifests (50.00%)
1713 bundling: 3/4 manifests (75.00%)
1714 bundling: 3/4 manifests (75.00%)
1714 bundling: 4/4 manifests (100.00%)
1715 bundling: 4/4 manifests (100.00%)
1715 bundling: abc.txt 1/4 files (25.00%)
1716 bundling: abc.txt 1/4 files (25.00%)
1716 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1717 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1717 bundling: foo/file.txt 3/4 files (75.00%)
1718 bundling: foo/file.txt 3/4 files (75.00%)
1718 bundling: quux/file.py 4/4 files (100.00%)
1719 bundling: quux/file.py 4/4 files (100.00%)
1719 changesets: 1 chunks
1720 changesets: 1 chunks
1720 add changeset ef1ea85a6374
1721 add changeset ef1ea85a6374
1721 changesets: 2 chunks
1722 changesets: 2 chunks
1722 add changeset f9cafe1212c8
1723 add changeset f9cafe1212c8
1723 changesets: 3 chunks
1724 changesets: 3 chunks
1724 add changeset 911600dab2ae
1725 add changeset 911600dab2ae
1725 changesets: 4 chunks
1726 changesets: 4 chunks
1726 add changeset e8fc755d4d82
1727 add changeset e8fc755d4d82
1727 adding manifests
1728 adding manifests
1728 manifests: 1/4 chunks (25.00%)
1729 manifests: 1/4 chunks (25.00%)
1729 manifests: 2/4 chunks (50.00%)
1730 manifests: 2/4 chunks (50.00%)
1730 manifests: 3/4 chunks (75.00%)
1731 manifests: 3/4 chunks (75.00%)
1731 manifests: 4/4 chunks (100.00%)
1732 manifests: 4/4 chunks (100.00%)
1732 adding file changes
1733 adding file changes
1733 adding abc.txt revisions
1734 adding abc.txt revisions
1734 files: 1/4 chunks (25.00%)
1735 files: 1/4 chunks (25.00%)
1735 adding foo/Bar/file.txt revisions
1736 adding foo/Bar/file.txt revisions
1736 files: 2/4 chunks (50.00%)
1737 files: 2/4 chunks (50.00%)
1737 adding foo/file.txt revisions
1738 adding foo/file.txt revisions
1738 files: 3/4 chunks (75.00%)
1739 files: 3/4 chunks (75.00%)
1739 adding quux/file.py revisions
1740 adding quux/file.py revisions
1740 files: 4/4 chunks (100.00%)
1741 files: 4/4 chunks (100.00%)
1741 added 4 changesets with 4 changes to 4 files (+1 heads)
1742 added 4 changesets with 4 changes to 4 files (+1 heads)
1742 calling hook pretxnchangegroup.acl: hgext.acl.hook
1743 calling hook pretxnchangegroup.acl: hgext.acl.hook
1743 acl: checking access for user "george"
1744 acl: checking access for user "george"
1744 acl: acl.allow.branches enabled, 1 entries for user george
1745 acl: acl.allow.branches enabled, 1 entries for user george
1745 acl: acl.deny.branches not enabled
1746 acl: acl.deny.branches not enabled
1746 acl: acl.allow not enabled
1747 acl: acl.allow not enabled
1747 acl: acl.deny not enabled
1748 acl: acl.deny not enabled
1748 acl: branch access granted: "ef1ea85a6374" on branch "default"
1749 acl: branch access granted: "ef1ea85a6374" on branch "default"
1749 acl: path access granted: "ef1ea85a6374"
1750 acl: path access granted: "ef1ea85a6374"
1750 acl: branch access granted: "f9cafe1212c8" on branch "default"
1751 acl: branch access granted: "f9cafe1212c8" on branch "default"
1751 acl: path access granted: "f9cafe1212c8"
1752 acl: path access granted: "f9cafe1212c8"
1752 acl: branch access granted: "911600dab2ae" on branch "default"
1753 acl: branch access granted: "911600dab2ae" on branch "default"
1753 acl: path access granted: "911600dab2ae"
1754 acl: path access granted: "911600dab2ae"
1754 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1755 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1755 acl: path access granted: "e8fc755d4d82"
1756 acl: path access granted: "e8fc755d4d82"
1756 updating the branch cache
1757 updating the branch cache
1757 checking for updated bookmarks
1758 checking for updated bookmarks
1758 repository tip rolled back to revision 2 (undo push)
1759 repository tip rolled back to revision 2 (undo push)
1759 2:fb35475503ef
1760 2:fb35475503ef
1760
1761
1761
1762
1762 Branch acl conflicting allow
1763 Branch acl conflicting allow
1763 asterisk ends up applying to all branches and allowing george to
1764 asterisk ends up applying to all branches and allowing george to
1764 push foobar into the remote
1765 push foobar into the remote
1765
1766
1766 $ init_config
1767 $ init_config
1767 $ echo "[acl.allow.branches]" >> $config
1768 $ echo "[acl.allow.branches]" >> $config
1768 $ echo "foobar = astro" >> $config
1769 $ echo "foobar = astro" >> $config
1769 $ echo "* = george" >> $config
1770 $ echo "* = george" >> $config
1770 $ do_push george
1771 $ do_push george
1771 Pushing as user george
1772 Pushing as user george
1772 hgrc = """
1773 hgrc = """
1773 [acl]
1774 [acl]
1774 sources = push
1775 sources = push
1775 [extensions]
1776 [extensions]
1776 [acl.allow.branches]
1777 [acl.allow.branches]
1777 foobar = astro
1778 foobar = astro
1778 * = george
1779 * = george
1779 """
1780 """
1780 pushing to ../b
1781 pushing to ../b
1781 query 1; heads
1782 query 1; heads
1782 searching for changes
1783 searching for changes
1783 all remote heads known locally
1784 all remote heads known locally
1784 invalidating branch cache (tip differs)
1785 invalidating branch cache (tip differs)
1785 4 changesets found
1786 4 changesets found
1786 list of changesets:
1787 list of changesets:
1787 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1788 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1788 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1789 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1789 911600dab2ae7a9baff75958b84fe606851ce955
1790 911600dab2ae7a9baff75958b84fe606851ce955
1790 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1791 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1791 adding changesets
1792 adding changesets
1792 bundling: 1/4 changesets (25.00%)
1793 bundling: 1/4 changesets (25.00%)
1793 bundling: 2/4 changesets (50.00%)
1794 bundling: 2/4 changesets (50.00%)
1794 bundling: 3/4 changesets (75.00%)
1795 bundling: 3/4 changesets (75.00%)
1795 bundling: 4/4 changesets (100.00%)
1796 bundling: 4/4 changesets (100.00%)
1796 bundling: 1/4 manifests (25.00%)
1797 bundling: 1/4 manifests (25.00%)
1797 bundling: 2/4 manifests (50.00%)
1798 bundling: 2/4 manifests (50.00%)
1798 bundling: 3/4 manifests (75.00%)
1799 bundling: 3/4 manifests (75.00%)
1799 bundling: 4/4 manifests (100.00%)
1800 bundling: 4/4 manifests (100.00%)
1800 bundling: abc.txt 1/4 files (25.00%)
1801 bundling: abc.txt 1/4 files (25.00%)
1801 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1802 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1802 bundling: foo/file.txt 3/4 files (75.00%)
1803 bundling: foo/file.txt 3/4 files (75.00%)
1803 bundling: quux/file.py 4/4 files (100.00%)
1804 bundling: quux/file.py 4/4 files (100.00%)
1804 changesets: 1 chunks
1805 changesets: 1 chunks
1805 add changeset ef1ea85a6374
1806 add changeset ef1ea85a6374
1806 changesets: 2 chunks
1807 changesets: 2 chunks
1807 add changeset f9cafe1212c8
1808 add changeset f9cafe1212c8
1808 changesets: 3 chunks
1809 changesets: 3 chunks
1809 add changeset 911600dab2ae
1810 add changeset 911600dab2ae
1810 changesets: 4 chunks
1811 changesets: 4 chunks
1811 add changeset e8fc755d4d82
1812 add changeset e8fc755d4d82
1812 adding manifests
1813 adding manifests
1813 manifests: 1/4 chunks (25.00%)
1814 manifests: 1/4 chunks (25.00%)
1814 manifests: 2/4 chunks (50.00%)
1815 manifests: 2/4 chunks (50.00%)
1815 manifests: 3/4 chunks (75.00%)
1816 manifests: 3/4 chunks (75.00%)
1816 manifests: 4/4 chunks (100.00%)
1817 manifests: 4/4 chunks (100.00%)
1817 adding file changes
1818 adding file changes
1818 adding abc.txt revisions
1819 adding abc.txt revisions
1819 files: 1/4 chunks (25.00%)
1820 files: 1/4 chunks (25.00%)
1820 adding foo/Bar/file.txt revisions
1821 adding foo/Bar/file.txt revisions
1821 files: 2/4 chunks (50.00%)
1822 files: 2/4 chunks (50.00%)
1822 adding foo/file.txt revisions
1823 adding foo/file.txt revisions
1823 files: 3/4 chunks (75.00%)
1824 files: 3/4 chunks (75.00%)
1824 adding quux/file.py revisions
1825 adding quux/file.py revisions
1825 files: 4/4 chunks (100.00%)
1826 files: 4/4 chunks (100.00%)
1826 added 4 changesets with 4 changes to 4 files (+1 heads)
1827 added 4 changesets with 4 changes to 4 files (+1 heads)
1827 calling hook pretxnchangegroup.acl: hgext.acl.hook
1828 calling hook pretxnchangegroup.acl: hgext.acl.hook
1828 acl: checking access for user "george"
1829 acl: checking access for user "george"
1829 acl: acl.allow.branches enabled, 1 entries for user george
1830 acl: acl.allow.branches enabled, 1 entries for user george
1830 acl: acl.deny.branches not enabled
1831 acl: acl.deny.branches not enabled
1831 acl: acl.allow not enabled
1832 acl: acl.allow not enabled
1832 acl: acl.deny not enabled
1833 acl: acl.deny not enabled
1833 acl: branch access granted: "ef1ea85a6374" on branch "default"
1834 acl: branch access granted: "ef1ea85a6374" on branch "default"
1834 acl: path access granted: "ef1ea85a6374"
1835 acl: path access granted: "ef1ea85a6374"
1835 acl: branch access granted: "f9cafe1212c8" on branch "default"
1836 acl: branch access granted: "f9cafe1212c8" on branch "default"
1836 acl: path access granted: "f9cafe1212c8"
1837 acl: path access granted: "f9cafe1212c8"
1837 acl: branch access granted: "911600dab2ae" on branch "default"
1838 acl: branch access granted: "911600dab2ae" on branch "default"
1838 acl: path access granted: "911600dab2ae"
1839 acl: path access granted: "911600dab2ae"
1839 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1840 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1840 acl: path access granted: "e8fc755d4d82"
1841 acl: path access granted: "e8fc755d4d82"
1841 updating the branch cache
1842 updating the branch cache
1842 checking for updated bookmarks
1843 checking for updated bookmarks
1843 repository tip rolled back to revision 2 (undo push)
1844 repository tip rolled back to revision 2 (undo push)
1844 2:fb35475503ef
1845 2:fb35475503ef
1845
1846
1846 Branch acl conflicting deny
1847 Branch acl conflicting deny
1847
1848
1848 $ init_config
1849 $ init_config
1849 $ echo "[acl.deny.branches]" >> $config
1850 $ echo "[acl.deny.branches]" >> $config
1850 $ echo "foobar = astro" >> $config
1851 $ echo "foobar = astro" >> $config
1851 $ echo "default = astro" >> $config
1852 $ echo "default = astro" >> $config
1852 $ echo "* = george" >> $config
1853 $ echo "* = george" >> $config
1853 $ do_push george
1854 $ do_push george
1854 Pushing as user george
1855 Pushing as user george
1855 hgrc = """
1856 hgrc = """
1856 [acl]
1857 [acl]
1857 sources = push
1858 sources = push
1858 [extensions]
1859 [extensions]
1859 [acl.deny.branches]
1860 [acl.deny.branches]
1860 foobar = astro
1861 foobar = astro
1861 default = astro
1862 default = astro
1862 * = george
1863 * = george
1863 """
1864 """
1864 pushing to ../b
1865 pushing to ../b
1865 query 1; heads
1866 query 1; heads
1866 searching for changes
1867 searching for changes
1867 all remote heads known locally
1868 all remote heads known locally
1868 invalidating branch cache (tip differs)
1869 invalidating branch cache (tip differs)
1869 4 changesets found
1870 4 changesets found
1870 list of changesets:
1871 list of changesets:
1871 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1872 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1872 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1873 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1873 911600dab2ae7a9baff75958b84fe606851ce955
1874 911600dab2ae7a9baff75958b84fe606851ce955
1874 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1875 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1875 adding changesets
1876 adding changesets
1876 bundling: 1/4 changesets (25.00%)
1877 bundling: 1/4 changesets (25.00%)
1877 bundling: 2/4 changesets (50.00%)
1878 bundling: 2/4 changesets (50.00%)
1878 bundling: 3/4 changesets (75.00%)
1879 bundling: 3/4 changesets (75.00%)
1879 bundling: 4/4 changesets (100.00%)
1880 bundling: 4/4 changesets (100.00%)
1880 bundling: 1/4 manifests (25.00%)
1881 bundling: 1/4 manifests (25.00%)
1881 bundling: 2/4 manifests (50.00%)
1882 bundling: 2/4 manifests (50.00%)
1882 bundling: 3/4 manifests (75.00%)
1883 bundling: 3/4 manifests (75.00%)
1883 bundling: 4/4 manifests (100.00%)
1884 bundling: 4/4 manifests (100.00%)
1884 bundling: abc.txt 1/4 files (25.00%)
1885 bundling: abc.txt 1/4 files (25.00%)
1885 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1886 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1886 bundling: foo/file.txt 3/4 files (75.00%)
1887 bundling: foo/file.txt 3/4 files (75.00%)
1887 bundling: quux/file.py 4/4 files (100.00%)
1888 bundling: quux/file.py 4/4 files (100.00%)
1888 changesets: 1 chunks
1889 changesets: 1 chunks
1889 add changeset ef1ea85a6374
1890 add changeset ef1ea85a6374
1890 changesets: 2 chunks
1891 changesets: 2 chunks
1891 add changeset f9cafe1212c8
1892 add changeset f9cafe1212c8
1892 changesets: 3 chunks
1893 changesets: 3 chunks
1893 add changeset 911600dab2ae
1894 add changeset 911600dab2ae
1894 changesets: 4 chunks
1895 changesets: 4 chunks
1895 add changeset e8fc755d4d82
1896 add changeset e8fc755d4d82
1896 adding manifests
1897 adding manifests
1897 manifests: 1/4 chunks (25.00%)
1898 manifests: 1/4 chunks (25.00%)
1898 manifests: 2/4 chunks (50.00%)
1899 manifests: 2/4 chunks (50.00%)
1899 manifests: 3/4 chunks (75.00%)
1900 manifests: 3/4 chunks (75.00%)
1900 manifests: 4/4 chunks (100.00%)
1901 manifests: 4/4 chunks (100.00%)
1901 adding file changes
1902 adding file changes
1902 adding abc.txt revisions
1903 adding abc.txt revisions
1903 files: 1/4 chunks (25.00%)
1904 files: 1/4 chunks (25.00%)
1904 adding foo/Bar/file.txt revisions
1905 adding foo/Bar/file.txt revisions
1905 files: 2/4 chunks (50.00%)
1906 files: 2/4 chunks (50.00%)
1906 adding foo/file.txt revisions
1907 adding foo/file.txt revisions
1907 files: 3/4 chunks (75.00%)
1908 files: 3/4 chunks (75.00%)
1908 adding quux/file.py revisions
1909 adding quux/file.py revisions
1909 files: 4/4 chunks (100.00%)
1910 files: 4/4 chunks (100.00%)
1910 added 4 changesets with 4 changes to 4 files (+1 heads)
1911 added 4 changesets with 4 changes to 4 files (+1 heads)
1911 calling hook pretxnchangegroup.acl: hgext.acl.hook
1912 calling hook pretxnchangegroup.acl: hgext.acl.hook
1912 acl: checking access for user "george"
1913 acl: checking access for user "george"
1913 acl: acl.allow.branches not enabled
1914 acl: acl.allow.branches not enabled
1914 acl: acl.deny.branches enabled, 1 entries for user george
1915 acl: acl.deny.branches enabled, 1 entries for user george
1915 acl: acl.allow not enabled
1916 acl: acl.allow not enabled
1916 acl: acl.deny not enabled
1917 acl: acl.deny not enabled
1917 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1918 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1918 transaction abort!
1919 transaction abort!
1919 rollback completed
1920 rollback completed
1920 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1921 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1921 no rollback information available
1922 no rollback information available
1922 2:fb35475503ef
1923 2:fb35475503ef
1923
1924
@@ -1,288 +1,290 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
14
15 $ echo a > a
15 $ echo a > a
16 $ hg commit -d '0 0' -A -m a
16 $ hg commit -d '0 0' -A -m a
17 adding a
17 adding a
18 $ echo b >> a
18 $ echo b >> a
19 $ hg commit -d '1 0' -m b
19 $ hg commit -d '1 0' -m b
20
20
21 $ hg backout -d '2 0' tip --tool=true
21 $ hg backout -d '2 0' tip --tool=true
22 reverting a
22 reverting a
23 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
23 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
24 $ cat a
24 $ cat a
25 a
25 a
26
26
27 file that was removed is recreated
27 file that was removed is recreated
28
28
29 $ cd ..
29 $ cd ..
30 $ hg init remove
30 $ hg init remove
31 $ cd remove
31 $ cd remove
32
32
33 $ echo content > a
33 $ echo content > a
34 $ hg commit -d '0 0' -A -m a
34 $ hg commit -d '0 0' -A -m a
35 adding a
35 adding a
36
36
37 $ hg rm a
37 $ hg rm a
38 $ hg commit -d '1 0' -m b
38 $ hg commit -d '1 0' -m b
39
39
40 $ hg backout -d '2 0' tip --tool=true
40 $ hg backout -d '2 0' tip --tool=true
41 adding a
41 adding a
42 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
42 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
43 $ cat a
43 $ cat a
44 content
44 content
45
45
46 backout of backout is as if nothing happened
46 backout of backout is as if nothing happened
47
47
48 $ hg backout -d '3 0' --merge tip --tool=true
48 $ hg backout -d '3 0' --merge tip --tool=true
49 removing a
49 removing a
50 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
50 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
51 $ test -f a
51 $ test -f a
52 [1]
52 [1]
53
53
54 across branch
54 across branch
55
55
56 $ cd ..
56 $ cd ..
57 $ hg init branch
57 $ hg init branch
58 $ cd branch
58 $ cd branch
59 $ echo a > a
59 $ echo a > a
60 $ hg ci -Am0
60 $ hg ci -Am0
61 adding a
61 adding a
62 $ echo b > b
62 $ echo b > b
63 $ hg ci -Am1
63 $ hg ci -Am1
64 adding b
64 adding b
65 $ hg co -C 0
65 $ hg co -C 0
66 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
67
67
68 should fail
68 should fail
69
69
70 $ hg backout 1
70 $ hg backout 1
71 abort: cannot backout change on a different branch
71 abort: cannot backout change on a different branch
72 [255]
72 [255]
73 $ echo c > c
73 $ echo c > c
74 $ hg ci -Am2
74 $ hg ci -Am2
75 adding c
75 adding c
76 created new head
76 created new head
77
77
78 should fail
78 should fail
79
79
80 $ hg backout 1
80 $ hg backout 1
81 abort: cannot backout change on a different branch
81 abort: cannot backout change on a different branch
82 [255]
82 [255]
83
83
84 backout with merge
84 backout with merge
85
85
86 $ cd ..
86 $ cd ..
87 $ hg init merge
87 $ hg init merge
88 $ cd merge
88 $ cd merge
89
89
90 $ echo line 1 > a
90 $ echo line 1 > a
91 $ echo line 2 >> a
91 $ echo line 2 >> a
92 $ hg commit -d '0 0' -A -m a
92 $ hg commit -d '0 0' -A -m a
93 adding a
93 adding a
94
94
95 remove line 1
95 remove line 1
96
96
97 $ echo line 2 > a
97 $ echo line 2 > a
98 $ hg commit -d '1 0' -m b
98 $ hg commit -d '1 0' -m b
99
99
100 $ echo line 3 >> a
100 $ echo line 3 >> a
101 $ hg commit -d '2 0' -m c
101 $ hg commit -d '2 0' -m c
102
102
103 $ hg backout --merge -d '3 0' 1 --tool=true
103 $ hg backout --merge -d '3 0' 1 --tool=true
104 reverting a
104 reverting a
105 created new head
105 created new head
106 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
106 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
107 merging with changeset 3:26b8ccb9ad91
107 merging with changeset 3:26b8ccb9ad91
108 merging a
108 merging a
109 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
109 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
110 (branch merge, don't forget to commit)
110 (branch merge, don't forget to commit)
111 $ hg commit -d '4 0' -m d
111 $ hg commit -d '4 0' -m d
112
112
113 check line 1 is back
113 check line 1 is back
114
114
115 $ cat a
115 $ cat a
116 line 1
116 line 1
117 line 2
117 line 2
118 line 3
118 line 3
119
119
120 backout should not back out subsequent changesets
120 backout should not back out subsequent changesets
121
121
122 $ hg init onecs
122 $ hg init onecs
123 $ cd onecs
123 $ cd onecs
124 $ echo 1 > a
124 $ echo 1 > a
125 $ hg commit -d '0 0' -A -m a
125 $ hg commit -d '0 0' -A -m a
126 adding a
126 adding a
127 $ echo 2 >> a
127 $ echo 2 >> a
128 $ hg commit -d '1 0' -m b
128 $ hg commit -d '1 0' -m b
129 $ echo 1 > b
129 $ echo 1 > b
130 $ hg commit -d '2 0' -A -m c
130 $ hg commit -d '2 0' -A -m c
131 adding b
131 adding b
132
132
133 without --merge
133 without --merge
134 $ hg backout -d '3 0' 1 --tool=true
134 $ hg backout -d '3 0' 1 --tool=true
135 reverting a
135 reverting a
136 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
137 $ hg locate b
137 $ hg locate b
138 b
138 b
139 $ hg update -C tip
139 $ hg update -C tip
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 $ hg locate b
141 $ hg locate b
142 b
142 b
143
143
144 with --merge
144 with --merge
145 $ hg backout --merge -d '3 0' 1 --tool=true
145 $ hg backout --merge -d '3 0' 1 --tool=true
146 reverting a
146 reverting a
147 created new head
147 created new head
148 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
148 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
149 merging with changeset 3:3202beb76721
149 merging with changeset 3:3202beb76721
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 (branch merge, don't forget to commit)
151 (branch merge, don't forget to commit)
152 $ hg locate b
152 $ hg locate b
153 b
153 b
154 $ hg update -C tip
154 $ hg update -C tip
155 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
155 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
156 $ hg locate b
156 $ hg locate b
157 [1]
157 [1]
158
158
159 $ cd ..
159 $ cd ..
160 $ hg init m
160 $ hg init m
161 $ cd m
161 $ cd m
162 $ echo a > a
162 $ echo a > a
163 $ hg commit -d '0 0' -A -m a
163 $ hg commit -d '0 0' -A -m a
164 adding a
164 adding a
165 $ echo b > b
165 $ echo b > b
166 $ hg commit -d '1 0' -A -m b
166 $ hg commit -d '1 0' -A -m b
167 adding b
167 adding b
168 $ echo c > c
168 $ echo c > c
169 $ hg commit -d '2 0' -A -m b
169 $ hg commit -d '2 0' -A -m b
170 adding c
170 adding c
171 $ hg update 1
171 $ hg update 1
172 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
172 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 $ echo d > d
173 $ echo d > d
174 $ hg commit -d '3 0' -A -m c
174 $ hg commit -d '3 0' -A -m c
175 adding d
175 adding d
176 created new head
176 created new head
177 $ hg merge 2
177 $ hg merge 2
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 (branch merge, don't forget to commit)
179 (branch merge, don't forget to commit)
180 $ hg commit -d '4 0' -A -m d
180 $ hg commit -d '4 0' -A -m d
181
181
182 backout of merge should fail
182 backout of merge should fail
183
183
184 $ hg backout 4
184 $ hg backout 4
185 abort: cannot backout a merge changeset
185 abort: cannot backout a merge changeset
186 [255]
186 [255]
187
187
188 backout of merge with bad parent should fail
188 backout of merge with bad parent should fail
189
189
190 $ hg backout --parent 0 4
190 $ hg backout --parent 0 4
191 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
191 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
192 [255]
192 [255]
193
193
194 backout of non-merge with parent should fail
194 backout of non-merge with parent should fail
195
195
196 $ hg backout --parent 0 3
196 $ hg backout --parent 0 3
197 abort: cannot use --parent on non-merge changeset
197 abort: cannot use --parent on non-merge changeset
198 [255]
198 [255]
199
199
200 backout with valid parent should be ok
200 backout with valid parent should be ok
201
201
202 $ hg backout -d '5 0' --parent 2 4 --tool=true
202 $ hg backout -d '5 0' --parent 2 4 --tool=true
203 removing d
203 removing d
204 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
204 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
205
205
206 $ hg rollback
206 $ hg rollback
207 repository tip rolled back to revision 4 (undo commit)
207 repository tip rolled back to revision 4 (undo commit)
208 working directory now based on revision 4
208 working directory now based on revision 4
209 $ hg update -C
209 $ hg update -C
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
211
211
212 $ hg backout -d '6 0' --parent 3 4 --tool=true
212 $ hg backout -d '6 0' --parent 3 4 --tool=true
213 removing c
213 removing c
214 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
214 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
215
215
216 $ cd ..
216 $ cd ..
217
217
218 named branches
218 named branches
219
219
220 $ hg init named_branches
220 $ hg init named_branches
221 $ cd named_branches
221 $ cd named_branches
222
222
223 $ echo default > default
223 $ echo default > default
224 $ hg ci -d '0 0' -Am default
224 $ hg ci -d '0 0' -Am default
225 adding default
225 adding default
226 $ hg branch branch1
226 $ hg branch branch1
227 marked working directory as branch branch1
227 marked working directory as branch branch1
228 (branches are permanent and global, did you want a bookmark?)
228 $ echo branch1 > file1
229 $ echo branch1 > file1
229 $ hg ci -d '1 0' -Am file1
230 $ hg ci -d '1 0' -Am file1
230 adding file1
231 adding file1
231 $ hg branch branch2
232 $ hg branch branch2
232 marked working directory as branch branch2
233 marked working directory as branch branch2
234 (branches are permanent and global, did you want a bookmark?)
233 $ echo branch2 > file2
235 $ echo branch2 > file2
234 $ hg ci -d '2 0' -Am file2
236 $ hg ci -d '2 0' -Am file2
235 adding file2
237 adding file2
236
238
237 without --merge
239 without --merge
238 $ hg backout -r 1 --tool=true
240 $ hg backout -r 1 --tool=true
239 removing file1
241 removing file1
240 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
242 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 $ hg branch
243 $ hg branch
242 branch2
244 branch2
243 $ hg status -A
245 $ hg status -A
244 R file1
246 R file1
245 C default
247 C default
246 C file2
248 C file2
247
249
248 with --merge
250 with --merge
249 $ hg update -qC
251 $ hg update -qC
250 $ hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true
252 $ hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true
251 removing file1
253 removing file1
252 created new head
254 created new head
253 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
255 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
254 merging with changeset 3:d4e8f6db59fb
256 merging with changeset 3:d4e8f6db59fb
255 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
257 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
256 (branch merge, don't forget to commit)
258 (branch merge, don't forget to commit)
257 $ hg update -q -C 2
259 $ hg update -q -C 2
258
260
259 on branch2 with branch1 not merged, so file1 should still exist:
261 on branch2 with branch1 not merged, so file1 should still exist:
260
262
261 $ hg id
263 $ hg id
262 45bbcd363bf0 (branch2)
264 45bbcd363bf0 (branch2)
263 $ hg st -A
265 $ hg st -A
264 C default
266 C default
265 C file1
267 C file1
266 C file2
268 C file2
267
269
268 on branch2 with branch1 merged, so file1 should be gone:
270 on branch2 with branch1 merged, so file1 should be gone:
269
271
270 $ hg merge
272 $ hg merge
271 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
273 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
272 (branch merge, don't forget to commit)
274 (branch merge, don't forget to commit)
273 $ hg ci -d '4 0' -m 'merge backout of branch1'
275 $ hg ci -d '4 0' -m 'merge backout of branch1'
274 $ hg id
276 $ hg id
275 22149cdde76d (branch2) tip
277 22149cdde76d (branch2) tip
276 $ hg st -A
278 $ hg st -A
277 C default
279 C default
278 C file2
280 C file2
279
281
280 on branch1, so no file1 and file2:
282 on branch1, so no file1 and file2:
281
283
282 $ hg co -C branch1
284 $ hg co -C branch1
283 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
285 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
284 $ hg id
286 $ hg id
285 bf1602f437f3 (branch1)
287 bf1602f437f3 (branch1)
286 $ hg st -A
288 $ hg st -A
287 C default
289 C default
288 C file1
290 C file1
@@ -1,367 +1,374 b''
1 $ heads()
1 $ heads()
2 > {
2 > {
3 > hg heads --template '{rev}: {desc|firstline|strip} ({branches})\n' "$@"
3 > hg heads --template '{rev}: {desc|firstline|strip} ({branches})\n' "$@"
4 > }
4 > }
5
5
6 $ hg init a
6 $ hg init a
7 $ cd a
7 $ cd a
8 $ echo 'root' >root
8 $ echo 'root' >root
9 $ hg add root
9 $ hg add root
10 $ hg commit -m "Adding root node"
10 $ hg commit -m "Adding root node"
11 $ heads
11 $ heads
12 0: Adding root node ()
12 0: Adding root node ()
13 -------
13 -------
14 $ heads .
14 $ heads .
15 0: Adding root node ()
15 0: Adding root node ()
16
16
17 =======
17 =======
18
18
19 $ echo 'a' >a
19 $ echo 'a' >a
20 $ hg add a
20 $ hg add a
21 $ hg branch a
21 $ hg branch a
22 marked working directory as branch a
22 marked working directory as branch a
23 (branches are permanent and global, did you want a bookmark?)
23 $ hg commit -m "Adding a branch"
24 $ hg commit -m "Adding a branch"
24 $ heads
25 $ heads
25 1: Adding a branch (a)
26 1: Adding a branch (a)
26 0: Adding root node ()
27 0: Adding root node ()
27 -------
28 -------
28 $ heads .
29 $ heads .
29 1: Adding a branch (a)
30 1: Adding a branch (a)
30
31
31 =======
32 =======
32
33
33 $ hg update -C 0
34 $ hg update -C 0
34 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
35 $ echo 'b' >b
36 $ echo 'b' >b
36 $ hg add b
37 $ hg add b
37 $ hg branch b
38 $ hg branch b
38 marked working directory as branch b
39 marked working directory as branch b
40 (branches are permanent and global, did you want a bookmark?)
39 $ hg commit -m "Adding b branch"
41 $ hg commit -m "Adding b branch"
40 $ heads
42 $ heads
41 2: Adding b branch (b)
43 2: Adding b branch (b)
42 1: Adding a branch (a)
44 1: Adding a branch (a)
43 0: Adding root node ()
45 0: Adding root node ()
44 -------
46 -------
45 $ heads .
47 $ heads .
46 2: Adding b branch (b)
48 2: Adding b branch (b)
47
49
48 =======
50 =======
49
51
50 $ echo 'bh1' >bh1
52 $ echo 'bh1' >bh1
51 $ hg add bh1
53 $ hg add bh1
52 $ hg commit -m "Adding b branch head 1"
54 $ hg commit -m "Adding b branch head 1"
53 $ heads
55 $ heads
54 3: Adding b branch head 1 (b)
56 3: Adding b branch head 1 (b)
55 1: Adding a branch (a)
57 1: Adding a branch (a)
56 0: Adding root node ()
58 0: Adding root node ()
57 -------
59 -------
58 $ heads .
60 $ heads .
59 3: Adding b branch head 1 (b)
61 3: Adding b branch head 1 (b)
60
62
61 =======
63 =======
62
64
63 $ hg update -C 2
65 $ hg update -C 2
64 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
65 $ echo 'bh2' >bh2
67 $ echo 'bh2' >bh2
66 $ hg add bh2
68 $ hg add bh2
67 $ hg commit -m "Adding b branch head 2"
69 $ hg commit -m "Adding b branch head 2"
68 created new head
70 created new head
69 $ heads
71 $ heads
70 4: Adding b branch head 2 (b)
72 4: Adding b branch head 2 (b)
71 3: Adding b branch head 1 (b)
73 3: Adding b branch head 1 (b)
72 1: Adding a branch (a)
74 1: Adding a branch (a)
73 0: Adding root node ()
75 0: Adding root node ()
74 $ heads .
76 $ heads .
75 4: Adding b branch head 2 (b)
77 4: Adding b branch head 2 (b)
76 3: Adding b branch head 1 (b)
78 3: Adding b branch head 1 (b)
77
79
78 =======
80 =======
79
81
80 $ hg update -C 2
82 $ hg update -C 2
81 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
83 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
82 $ echo 'bh3' >bh3
84 $ echo 'bh3' >bh3
83 $ hg add bh3
85 $ hg add bh3
84 $ hg commit -m "Adding b branch head 3"
86 $ hg commit -m "Adding b branch head 3"
85 created new head
87 created new head
86 $ heads
88 $ heads
87 5: Adding b branch head 3 (b)
89 5: Adding b branch head 3 (b)
88 4: Adding b branch head 2 (b)
90 4: Adding b branch head 2 (b)
89 3: Adding b branch head 1 (b)
91 3: Adding b branch head 1 (b)
90 1: Adding a branch (a)
92 1: Adding a branch (a)
91 0: Adding root node ()
93 0: Adding root node ()
92 -------
94 -------
93 $ heads .
95 $ heads .
94 5: Adding b branch head 3 (b)
96 5: Adding b branch head 3 (b)
95 4: Adding b branch head 2 (b)
97 4: Adding b branch head 2 (b)
96 3: Adding b branch head 1 (b)
98 3: Adding b branch head 1 (b)
97
99
98 =======
100 =======
99
101
100 $ hg merge 4
102 $ hg merge 4
101 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
103 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 (branch merge, don't forget to commit)
104 (branch merge, don't forget to commit)
103 $ hg commit -m "Merging b branch head 2 and b branch head 3"
105 $ hg commit -m "Merging b branch head 2 and b branch head 3"
104 $ heads
106 $ heads
105 6: Merging b branch head 2 and b branch head 3 (b)
107 6: Merging b branch head 2 and b branch head 3 (b)
106 3: Adding b branch head 1 (b)
108 3: Adding b branch head 1 (b)
107 1: Adding a branch (a)
109 1: Adding a branch (a)
108 0: Adding root node ()
110 0: Adding root node ()
109 -------
111 -------
110 $ heads .
112 $ heads .
111 6: Merging b branch head 2 and b branch head 3 (b)
113 6: Merging b branch head 2 and b branch head 3 (b)
112 3: Adding b branch head 1 (b)
114 3: Adding b branch head 1 (b)
113
115
114 =======
116 =======
115
117
116 $ echo 'c' >c
118 $ echo 'c' >c
117 $ hg add c
119 $ hg add c
118 $ hg branch c
120 $ hg branch c
119 marked working directory as branch c
121 marked working directory as branch c
122 (branches are permanent and global, did you want a bookmark?)
120 $ hg commit -m "Adding c branch"
123 $ hg commit -m "Adding c branch"
121 $ heads
124 $ heads
122 7: Adding c branch (c)
125 7: Adding c branch (c)
123 6: Merging b branch head 2 and b branch head 3 (b)
126 6: Merging b branch head 2 and b branch head 3 (b)
124 3: Adding b branch head 1 (b)
127 3: Adding b branch head 1 (b)
125 1: Adding a branch (a)
128 1: Adding a branch (a)
126 0: Adding root node ()
129 0: Adding root node ()
127 -------
130 -------
128 $ heads .
131 $ heads .
129 7: Adding c branch (c)
132 7: Adding c branch (c)
130
133
131 =======
134 =======
132
135
133 $ heads -r 3 .
136 $ heads -r 3 .
134 no open branch heads found on branches c (started at 3)
137 no open branch heads found on branches c (started at 3)
135 [1]
138 [1]
136 $ heads -r 2 .
139 $ heads -r 2 .
137 7: Adding c branch (c)
140 7: Adding c branch (c)
138 -------
141 -------
139 $ hg update -C 4
142 $ hg update -C 4
140 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
143 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
141 -------
144 -------
142 $ heads -r 3 .
145 $ heads -r 3 .
143 3: Adding b branch head 1 (b)
146 3: Adding b branch head 1 (b)
144 -------
147 -------
145 $ heads -r 2 .
148 $ heads -r 2 .
146 6: Merging b branch head 2 and b branch head 3 (b)
149 6: Merging b branch head 2 and b branch head 3 (b)
147 3: Adding b branch head 1 (b)
150 3: Adding b branch head 1 (b)
148 -------
151 -------
149 $ heads -r 7 .
152 $ heads -r 7 .
150 no open branch heads found on branches b (started at 7)
153 no open branch heads found on branches b (started at 7)
151 [1]
154 [1]
152
155
153 =======
156 =======
154
157
155 $ for i in 0 1 2 3 4 5 6 7; do
158 $ for i in 0 1 2 3 4 5 6 7; do
156 > hg update -C "$i"
159 > hg update -C "$i"
157 > heads
160 > heads
158 > echo '-------'
161 > echo '-------'
159 > heads .
162 > heads .
160 > echo '-------'
163 > echo '-------'
161 > done
164 > done
162 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
165 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
163 7: Adding c branch (c)
166 7: Adding c branch (c)
164 6: Merging b branch head 2 and b branch head 3 (b)
167 6: Merging b branch head 2 and b branch head 3 (b)
165 3: Adding b branch head 1 (b)
168 3: Adding b branch head 1 (b)
166 1: Adding a branch (a)
169 1: Adding a branch (a)
167 0: Adding root node ()
170 0: Adding root node ()
168 -------
171 -------
169 0: Adding root node ()
172 0: Adding root node ()
170 -------
173 -------
171 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 7: Adding c branch (c)
175 7: Adding c branch (c)
173 6: Merging b branch head 2 and b branch head 3 (b)
176 6: Merging b branch head 2 and b branch head 3 (b)
174 3: Adding b branch head 1 (b)
177 3: Adding b branch head 1 (b)
175 1: Adding a branch (a)
178 1: Adding a branch (a)
176 0: Adding root node ()
179 0: Adding root node ()
177 -------
180 -------
178 1: Adding a branch (a)
181 1: Adding a branch (a)
179 -------
182 -------
180 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
183 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
181 7: Adding c branch (c)
184 7: Adding c branch (c)
182 6: Merging b branch head 2 and b branch head 3 (b)
185 6: Merging b branch head 2 and b branch head 3 (b)
183 3: Adding b branch head 1 (b)
186 3: Adding b branch head 1 (b)
184 1: Adding a branch (a)
187 1: Adding a branch (a)
185 0: Adding root node ()
188 0: Adding root node ()
186 -------
189 -------
187 6: Merging b branch head 2 and b branch head 3 (b)
190 6: Merging b branch head 2 and b branch head 3 (b)
188 3: Adding b branch head 1 (b)
191 3: Adding b branch head 1 (b)
189 -------
192 -------
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 7: Adding c branch (c)
194 7: Adding c branch (c)
192 6: Merging b branch head 2 and b branch head 3 (b)
195 6: Merging b branch head 2 and b branch head 3 (b)
193 3: Adding b branch head 1 (b)
196 3: Adding b branch head 1 (b)
194 1: Adding a branch (a)
197 1: Adding a branch (a)
195 0: Adding root node ()
198 0: Adding root node ()
196 -------
199 -------
197 6: Merging b branch head 2 and b branch head 3 (b)
200 6: Merging b branch head 2 and b branch head 3 (b)
198 3: Adding b branch head 1 (b)
201 3: Adding b branch head 1 (b)
199 -------
202 -------
200 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
203 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
201 7: Adding c branch (c)
204 7: Adding c branch (c)
202 6: Merging b branch head 2 and b branch head 3 (b)
205 6: Merging b branch head 2 and b branch head 3 (b)
203 3: Adding b branch head 1 (b)
206 3: Adding b branch head 1 (b)
204 1: Adding a branch (a)
207 1: Adding a branch (a)
205 0: Adding root node ()
208 0: Adding root node ()
206 -------
209 -------
207 6: Merging b branch head 2 and b branch head 3 (b)
210 6: Merging b branch head 2 and b branch head 3 (b)
208 3: Adding b branch head 1 (b)
211 3: Adding b branch head 1 (b)
209 -------
212 -------
210 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
213 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
211 7: Adding c branch (c)
214 7: Adding c branch (c)
212 6: Merging b branch head 2 and b branch head 3 (b)
215 6: Merging b branch head 2 and b branch head 3 (b)
213 3: Adding b branch head 1 (b)
216 3: Adding b branch head 1 (b)
214 1: Adding a branch (a)
217 1: Adding a branch (a)
215 0: Adding root node ()
218 0: Adding root node ()
216 -------
219 -------
217 6: Merging b branch head 2 and b branch head 3 (b)
220 6: Merging b branch head 2 and b branch head 3 (b)
218 3: Adding b branch head 1 (b)
221 3: Adding b branch head 1 (b)
219 -------
222 -------
220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 7: Adding c branch (c)
224 7: Adding c branch (c)
222 6: Merging b branch head 2 and b branch head 3 (b)
225 6: Merging b branch head 2 and b branch head 3 (b)
223 3: Adding b branch head 1 (b)
226 3: Adding b branch head 1 (b)
224 1: Adding a branch (a)
227 1: Adding a branch (a)
225 0: Adding root node ()
228 0: Adding root node ()
226 -------
229 -------
227 6: Merging b branch head 2 and b branch head 3 (b)
230 6: Merging b branch head 2 and b branch head 3 (b)
228 3: Adding b branch head 1 (b)
231 3: Adding b branch head 1 (b)
229 -------
232 -------
230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 7: Adding c branch (c)
234 7: Adding c branch (c)
232 6: Merging b branch head 2 and b branch head 3 (b)
235 6: Merging b branch head 2 and b branch head 3 (b)
233 3: Adding b branch head 1 (b)
236 3: Adding b branch head 1 (b)
234 1: Adding a branch (a)
237 1: Adding a branch (a)
235 0: Adding root node ()
238 0: Adding root node ()
236 -------
239 -------
237 7: Adding c branch (c)
240 7: Adding c branch (c)
238 -------
241 -------
239
242
240 =======
243 =======
241
244
242 $ for i in a b c z; do
245 $ for i in a b c z; do
243 > heads "$i"
246 > heads "$i"
244 > echo '-------'
247 > echo '-------'
245 > done
248 > done
246 1: Adding a branch (a)
249 1: Adding a branch (a)
247 -------
250 -------
248 6: Merging b branch head 2 and b branch head 3 (b)
251 6: Merging b branch head 2 and b branch head 3 (b)
249 3: Adding b branch head 1 (b)
252 3: Adding b branch head 1 (b)
250 -------
253 -------
251 7: Adding c branch (c)
254 7: Adding c branch (c)
252 -------
255 -------
253 abort: unknown revision 'z'!
256 abort: unknown revision 'z'!
254 -------
257 -------
255
258
256 =======
259 =======
257
260
258 $ heads 0 1 2 3 4 5 6 7
261 $ heads 0 1 2 3 4 5 6 7
259 7: Adding c branch (c)
262 7: Adding c branch (c)
260 6: Merging b branch head 2 and b branch head 3 (b)
263 6: Merging b branch head 2 and b branch head 3 (b)
261 3: Adding b branch head 1 (b)
264 3: Adding b branch head 1 (b)
262 1: Adding a branch (a)
265 1: Adding a branch (a)
263 0: Adding root node ()
266 0: Adding root node ()
264
267
265 Topological heads:
268 Topological heads:
266
269
267 $ heads -t
270 $ heads -t
268 7: Adding c branch (c)
271 7: Adding c branch (c)
269 3: Adding b branch head 1 (b)
272 3: Adding b branch head 1 (b)
270 1: Adding a branch (a)
273 1: Adding a branch (a)
271
274
272 $ cd ..
275 $ cd ..
273 ______________
276 ______________
274
277
275 "created new head" message tests
278 "created new head" message tests
276
279
277 $ hg init newheadmsg
280 $ hg init newheadmsg
278 $ cd newheadmsg
281 $ cd newheadmsg
279
282
280 Init: no msg
283 Init: no msg
281
284
282 $ echo 1 > a
285 $ echo 1 > a
283 $ hg ci -Am "a0: Initial root"
286 $ hg ci -Am "a0: Initial root"
284 adding a
287 adding a
285 $ echo 2 >> a
288 $ echo 2 >> a
286 $ hg ci -m "a1 (HN)"
289 $ hg ci -m "a1 (HN)"
287
290
288 $ hg branch b
291 $ hg branch b
289 marked working directory as branch b
292 marked working directory as branch b
293 (branches are permanent and global, did you want a bookmark?)
290 $ echo 1 > b
294 $ echo 1 > b
291 $ hg ci -Am "b2: Initial root for branch b"
295 $ hg ci -Am "b2: Initial root for branch b"
292 adding b
296 adding b
293 $ echo 2 >> b
297 $ echo 2 >> b
294 $ hg ci -m "b3 (HN)"
298 $ hg ci -m "b3 (HN)"
295
299
296 Case NN: msg
300 Case NN: msg
297
301
298 $ hg up -q null
302 $ hg up -q null
299 $ hg branch -f b
303 $ hg branch -f b
300 marked working directory as branch b
304 marked working directory as branch b
305 (branches are permanent and global, did you want a bookmark?)
301 $ echo 1 > bb
306 $ echo 1 > bb
302 $ hg ci -Am "b4 (NN): new topo root for branch b"
307 $ hg ci -Am "b4 (NN): new topo root for branch b"
303 adding bb
308 adding bb
304 created new head
309 created new head
305
310
306 Case HN: no msg
311 Case HN: no msg
307
312
308 $ echo 2 >> bb
313 $ echo 2 >> bb
309 $ hg ci -m "b5 (HN)"
314 $ hg ci -m "b5 (HN)"
310
315
311 Case BN: msg
316 Case BN: msg
312
317
313 $ hg branch -f default
318 $ hg branch -f default
314 marked working directory as branch default
319 marked working directory as branch default
320 (branches are permanent and global, did you want a bookmark?)
315 $ echo 1 > aa
321 $ echo 1 > aa
316 $ hg ci -Am "a6 (BN): new branch root"
322 $ hg ci -Am "a6 (BN): new branch root"
317 adding aa
323 adding aa
318 created new head
324 created new head
319
325
320 Case CN: msg
326 Case CN: msg
321
327
322 $ hg up -q 4
328 $ hg up -q 4
323 $ echo 3 >> bbb
329 $ echo 3 >> bbb
324 $ hg ci -Am "b7 (CN): regular new head"
330 $ hg ci -Am "b7 (CN): regular new head"
325 adding bbb
331 adding bbb
326 created new head
332 created new head
327
333
328 Case BB: msg
334 Case BB: msg
329
335
330 $ hg up -q 4
336 $ hg up -q 4
331 $ hg merge -q 3
337 $ hg merge -q 3
332 $ hg branch -f default
338 $ hg branch -f default
333 marked working directory as branch default
339 marked working directory as branch default
340 (branches are permanent and global, did you want a bookmark?)
334 $ hg ci -m "a8 (BB): weird new branch root"
341 $ hg ci -m "a8 (BB): weird new branch root"
335 created new head
342 created new head
336
343
337 Case CB: msg
344 Case CB: msg
338
345
339 $ hg up -q 4
346 $ hg up -q 4
340 $ hg merge -q 1
347 $ hg merge -q 1
341 $ hg ci -m "b9 (CB): new head from branch merge"
348 $ hg ci -m "b9 (CB): new head from branch merge"
342 created new head
349 created new head
343
350
344 Case HB: no msg
351 Case HB: no msg
345
352
346 $ hg up -q 7
353 $ hg up -q 7
347 $ hg merge -q 6
354 $ hg merge -q 6
348 $ hg ci -m "b10 (HB): continuing head from branch merge"
355 $ hg ci -m "b10 (HB): continuing head from branch merge"
349
356
350 Case CC: msg
357 Case CC: msg
351
358
352 $ hg up -q 4
359 $ hg up -q 4
353 $ hg merge -q 2
360 $ hg merge -q 2
354 $ hg ci -m "b11 (CC): new head from merge"
361 $ hg ci -m "b11 (CC): new head from merge"
355 created new head
362 created new head
356
363
357 Case CH: no msg
364 Case CH: no msg
358
365
359 $ hg up -q 2
366 $ hg up -q 2
360 $ hg merge -q 10
367 $ hg merge -q 10
361 $ hg ci -m "b12 (CH): continuing head from merge"
368 $ hg ci -m "b12 (CH): continuing head from merge"
362
369
363 Case HH: no msg
370 Case HH: no msg
364
371
365 $ hg merge -q 3
372 $ hg merge -q 3
366 $ hg ci -m "b12 (HH): merging two heads"
373 $ hg ci -m "b12 (HH): merging two heads"
367
374
@@ -1,361 +1,362 b''
1 $ hg init
1 $ hg init
2
2
3 no bookmarks
3 no bookmarks
4
4
5 $ hg bookmarks
5 $ hg bookmarks
6 no bookmarks set
6 no bookmarks set
7
7
8 bookmark rev -1
8 bookmark rev -1
9
9
10 $ hg bookmark X
10 $ hg bookmark X
11
11
12 list bookmarks
12 list bookmarks
13
13
14 $ hg bookmarks
14 $ hg bookmarks
15 * X -1:000000000000
15 * X -1:000000000000
16
16
17 list bookmarks with color
17 list bookmarks with color
18
18
19 $ hg --config extensions.color= --config color.mode=ansi \
19 $ hg --config extensions.color= --config color.mode=ansi \
20 > bookmarks --color=always
20 > bookmarks --color=always
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
22
22
23 $ echo a > a
23 $ echo a > a
24 $ hg add a
24 $ hg add a
25 $ hg commit -m 0
25 $ hg commit -m 0
26
26
27 bookmark X moved to rev 0
27 bookmark X moved to rev 0
28
28
29 $ hg bookmarks
29 $ hg bookmarks
30 * X 0:f7b1eb17ad24
30 * X 0:f7b1eb17ad24
31
31
32 look up bookmark
32 look up bookmark
33
33
34 $ hg log -r X
34 $ hg log -r X
35 changeset: 0:f7b1eb17ad24
35 changeset: 0:f7b1eb17ad24
36 bookmark: X
36 bookmark: X
37 tag: tip
37 tag: tip
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: 0
40 summary: 0
41
41
42
42
43 second bookmark for rev 0
43 second bookmark for rev 0
44
44
45 $ hg bookmark X2
45 $ hg bookmark X2
46
46
47 bookmark rev -1 again
47 bookmark rev -1 again
48
48
49 $ hg bookmark -r null Y
49 $ hg bookmark -r null Y
50
50
51 list bookmarks
51 list bookmarks
52
52
53 $ hg bookmarks
53 $ hg bookmarks
54 X 0:f7b1eb17ad24
54 X 0:f7b1eb17ad24
55 * X2 0:f7b1eb17ad24
55 * X2 0:f7b1eb17ad24
56 Y -1:000000000000
56 Y -1:000000000000
57
57
58 $ echo b > b
58 $ echo b > b
59 $ hg add b
59 $ hg add b
60 $ hg commit -m 1
60 $ hg commit -m 1
61
61
62 bookmarks revset
62 bookmarks revset
63
63
64 $ hg log -r 'bookmark()'
64 $ hg log -r 'bookmark()'
65 changeset: 0:f7b1eb17ad24
65 changeset: 0:f7b1eb17ad24
66 bookmark: X
66 bookmark: X
67 user: test
67 user: test
68 date: Thu Jan 01 00:00:00 1970 +0000
68 date: Thu Jan 01 00:00:00 1970 +0000
69 summary: 0
69 summary: 0
70
70
71 changeset: 1:925d80f479bb
71 changeset: 1:925d80f479bb
72 bookmark: X2
72 bookmark: X2
73 tag: tip
73 tag: tip
74 user: test
74 user: test
75 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
76 summary: 1
76 summary: 1
77
77
78 $ hg log -r 'bookmark(Y)'
78 $ hg log -r 'bookmark(Y)'
79 $ hg log -r 'bookmark(X2)'
79 $ hg log -r 'bookmark(X2)'
80 changeset: 1:925d80f479bb
80 changeset: 1:925d80f479bb
81 bookmark: X2
81 bookmark: X2
82 tag: tip
82 tag: tip
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:00 1970 +0000
84 date: Thu Jan 01 00:00:00 1970 +0000
85 summary: 1
85 summary: 1
86
86
87 $ hg log -r 'bookmark(unknown)'
87 $ hg log -r 'bookmark(unknown)'
88 abort: bookmark 'unknown' does not exist
88 abort: bookmark 'unknown' does not exist
89 [255]
89 [255]
90
90
91 $ hg help revsets | grep 'bookmark('
91 $ hg help revsets | grep 'bookmark('
92 "bookmark([name])"
92 "bookmark([name])"
93
93
94 bookmarks X and X2 moved to rev 1, Y at rev -1
94 bookmarks X and X2 moved to rev 1, Y at rev -1
95
95
96 $ hg bookmarks
96 $ hg bookmarks
97 X 0:f7b1eb17ad24
97 X 0:f7b1eb17ad24
98 * X2 1:925d80f479bb
98 * X2 1:925d80f479bb
99 Y -1:000000000000
99 Y -1:000000000000
100
100
101 bookmark rev 0 again
101 bookmark rev 0 again
102
102
103 $ hg bookmark -r 0 Z
103 $ hg bookmark -r 0 Z
104
104
105 $ hg update X
105 $ hg update X
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
107 $ echo c > c
107 $ echo c > c
108 $ hg add c
108 $ hg add c
109 $ hg commit -m 2
109 $ hg commit -m 2
110 created new head
110 created new head
111
111
112 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
112 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
113
113
114 $ hg bookmarks
114 $ hg bookmarks
115 * X 2:db815d6d32e6
115 * X 2:db815d6d32e6
116 X2 1:925d80f479bb
116 X2 1:925d80f479bb
117 Y -1:000000000000
117 Y -1:000000000000
118 Z 0:f7b1eb17ad24
118 Z 0:f7b1eb17ad24
119
119
120 rename nonexistent bookmark
120 rename nonexistent bookmark
121
121
122 $ hg bookmark -m A B
122 $ hg bookmark -m A B
123 abort: bookmark 'A' does not exist
123 abort: bookmark 'A' does not exist
124 [255]
124 [255]
125
125
126 rename to existent bookmark
126 rename to existent bookmark
127
127
128 $ hg bookmark -m X Y
128 $ hg bookmark -m X Y
129 abort: bookmark 'Y' already exists (use -f to force)
129 abort: bookmark 'Y' already exists (use -f to force)
130 [255]
130 [255]
131
131
132 force rename to existent bookmark
132 force rename to existent bookmark
133
133
134 $ hg bookmark -f -m X Y
134 $ hg bookmark -f -m X Y
135
135
136 list bookmarks
136 list bookmarks
137
137
138 $ hg bookmark
138 $ hg bookmark
139 X2 1:925d80f479bb
139 X2 1:925d80f479bb
140 * Y 2:db815d6d32e6
140 * Y 2:db815d6d32e6
141 Z 0:f7b1eb17ad24
141 Z 0:f7b1eb17ad24
142
142
143 rename without new name
143 rename without new name
144
144
145 $ hg bookmark -m Y
145 $ hg bookmark -m Y
146 abort: new bookmark name required
146 abort: new bookmark name required
147 [255]
147 [255]
148
148
149 delete without name
149 delete without name
150
150
151 $ hg bookmark -d
151 $ hg bookmark -d
152 abort: bookmark name required
152 abort: bookmark name required
153 [255]
153 [255]
154
154
155 delete nonexistent bookmark
155 delete nonexistent bookmark
156
156
157 $ hg bookmark -d A
157 $ hg bookmark -d A
158 abort: bookmark 'A' does not exist
158 abort: bookmark 'A' does not exist
159 [255]
159 [255]
160
160
161 bookmark name with spaces should be stripped
161 bookmark name with spaces should be stripped
162
162
163 $ hg bookmark ' x y '
163 $ hg bookmark ' x y '
164
164
165 list bookmarks
165 list bookmarks
166
166
167 $ hg bookmarks
167 $ hg bookmarks
168 X2 1:925d80f479bb
168 X2 1:925d80f479bb
169 Y 2:db815d6d32e6
169 Y 2:db815d6d32e6
170 Z 0:f7b1eb17ad24
170 Z 0:f7b1eb17ad24
171 * x y 2:db815d6d32e6
171 * x y 2:db815d6d32e6
172
172
173 look up stripped bookmark name
173 look up stripped bookmark name
174
174
175 $ hg log -r '"x y"'
175 $ hg log -r '"x y"'
176 changeset: 2:db815d6d32e6
176 changeset: 2:db815d6d32e6
177 bookmark: Y
177 bookmark: Y
178 bookmark: x y
178 bookmark: x y
179 tag: tip
179 tag: tip
180 parent: 0:f7b1eb17ad24
180 parent: 0:f7b1eb17ad24
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:00 1970 +0000
182 date: Thu Jan 01 00:00:00 1970 +0000
183 summary: 2
183 summary: 2
184
184
185
185
186 reject bookmark name with newline
186 reject bookmark name with newline
187
187
188 $ hg bookmark '
188 $ hg bookmark '
189 > '
189 > '
190 abort: bookmark name cannot contain newlines
190 abort: bookmark name cannot contain newlines
191 [255]
191 [255]
192
192
193 bookmark with existing name
193 bookmark with existing name
194
194
195 $ hg bookmark Z
195 $ hg bookmark Z
196 abort: bookmark 'Z' already exists (use -f to force)
196 abort: bookmark 'Z' already exists (use -f to force)
197 [255]
197 [255]
198
198
199 force bookmark with existing name
199 force bookmark with existing name
200
200
201 $ hg bookmark -f Z
201 $ hg bookmark -f Z
202
202
203 list bookmarks
203 list bookmarks
204
204
205 $ hg bookmark
205 $ hg bookmark
206 X2 1:925d80f479bb
206 X2 1:925d80f479bb
207 Y 2:db815d6d32e6
207 Y 2:db815d6d32e6
208 * Z 2:db815d6d32e6
208 * Z 2:db815d6d32e6
209 x y 2:db815d6d32e6
209 x y 2:db815d6d32e6
210
210
211 revision but no bookmark name
211 revision but no bookmark name
212
212
213 $ hg bookmark -r .
213 $ hg bookmark -r .
214 abort: bookmark name required
214 abort: bookmark name required
215 [255]
215 [255]
216
216
217 bookmark name with whitespace only
217 bookmark name with whitespace only
218
218
219 $ hg bookmark ' '
219 $ hg bookmark ' '
220 abort: bookmark names cannot consist entirely of whitespace
220 abort: bookmark names cannot consist entirely of whitespace
221 [255]
221 [255]
222
222
223 invalid bookmark
223 invalid bookmark
224
224
225 $ hg bookmark 'foo:bar'
225 $ hg bookmark 'foo:bar'
226 abort: bookmark 'foo:bar' contains illegal character
226 abort: bookmark 'foo:bar' contains illegal character
227 [255]
227 [255]
228
228
229 the bookmark extension should be ignored now that it is part of core
229 the bookmark extension should be ignored now that it is part of core
230
230
231 $ echo "[extensions]" >> $HGRCPATH
231 $ echo "[extensions]" >> $HGRCPATH
232 $ echo "bookmarks=" >> $HGRCPATH
232 $ echo "bookmarks=" >> $HGRCPATH
233 $ hg bookmarks
233 $ hg bookmarks
234 X2 1:925d80f479bb
234 X2 1:925d80f479bb
235 Y 2:db815d6d32e6
235 Y 2:db815d6d32e6
236 * Z 2:db815d6d32e6
236 * Z 2:db815d6d32e6
237 x y 2:db815d6d32e6
237 x y 2:db815d6d32e6
238
238
239 test summary
239 test summary
240
240
241 $ hg summary
241 $ hg summary
242 parent: 2:db815d6d32e6 tip
242 parent: 2:db815d6d32e6 tip
243 2
243 2
244 branch: default
244 branch: default
245 bookmarks: *Z Y x y
245 bookmarks: *Z Y x y
246 commit: (clean)
246 commit: (clean)
247 update: 1 new changesets, 2 branch heads (merge)
247 update: 1 new changesets, 2 branch heads (merge)
248
248
249 test id
249 test id
250
250
251 $ hg id
251 $ hg id
252 db815d6d32e6 tip Y/Z/x y
252 db815d6d32e6 tip Y/Z/x y
253
253
254 test rollback
254 test rollback
255
255
256 $ echo foo > f1
256 $ echo foo > f1
257 $ hg ci -Amr
257 $ hg ci -Amr
258 adding f1
258 adding f1
259 $ hg bookmark -f Y -r 1
259 $ hg bookmark -f Y -r 1
260 $ hg bookmark -f Z -r 1
260 $ hg bookmark -f Z -r 1
261 $ hg rollback
261 $ hg rollback
262 repository tip rolled back to revision 2 (undo commit)
262 repository tip rolled back to revision 2 (undo commit)
263 working directory now based on revision 2
263 working directory now based on revision 2
264 $ hg bookmarks
264 $ hg bookmarks
265 X2 1:925d80f479bb
265 X2 1:925d80f479bb
266 Y 2:db815d6d32e6
266 Y 2:db815d6d32e6
267 * Z 2:db815d6d32e6
267 * Z 2:db815d6d32e6
268 x y 2:db815d6d32e6
268 x y 2:db815d6d32e6
269
269
270 test clone
270 test clone
271
271
272 $ hg bookmarks
272 $ hg bookmarks
273 X2 1:925d80f479bb
273 X2 1:925d80f479bb
274 Y 2:db815d6d32e6
274 Y 2:db815d6d32e6
275 * Z 2:db815d6d32e6
275 * Z 2:db815d6d32e6
276 x y 2:db815d6d32e6
276 x y 2:db815d6d32e6
277 $ hg clone . cloned-bookmarks
277 $ hg clone . cloned-bookmarks
278 updating to branch default
278 updating to branch default
279 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 $ hg -R cloned-bookmarks bookmarks
280 $ hg -R cloned-bookmarks bookmarks
281 X2 1:925d80f479bb
281 X2 1:925d80f479bb
282 Y 2:db815d6d32e6
282 Y 2:db815d6d32e6
283 Z 2:db815d6d32e6
283 Z 2:db815d6d32e6
284 x y 2:db815d6d32e6
284 x y 2:db815d6d32e6
285
285
286 test clone with pull protocol
286 test clone with pull protocol
287
287
288 $ hg clone --pull . cloned-bookmarks-pull
288 $ hg clone --pull . cloned-bookmarks-pull
289 requesting all changes
289 requesting all changes
290 adding changesets
290 adding changesets
291 adding manifests
291 adding manifests
292 adding file changes
292 adding file changes
293 added 3 changesets with 3 changes to 3 files (+1 heads)
293 added 3 changesets with 3 changes to 3 files (+1 heads)
294 updating to branch default
294 updating to branch default
295 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
295 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 $ hg -R cloned-bookmarks-pull bookmarks
296 $ hg -R cloned-bookmarks-pull bookmarks
297 X2 1:925d80f479bb
297 X2 1:925d80f479bb
298 Y 2:db815d6d32e6
298 Y 2:db815d6d32e6
299 Z 2:db815d6d32e6
299 Z 2:db815d6d32e6
300 x y 2:db815d6d32e6
300 x y 2:db815d6d32e6
301
301
302 test clone with a specific revision
302 test clone with a specific revision
303
303
304 $ hg clone -r 925d80 . cloned-bookmarks-rev
304 $ hg clone -r 925d80 . cloned-bookmarks-rev
305 adding changesets
305 adding changesets
306 adding manifests
306 adding manifests
307 adding file changes
307 adding file changes
308 added 2 changesets with 2 changes to 2 files
308 added 2 changesets with 2 changes to 2 files
309 updating to branch default
309 updating to branch default
310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 $ hg -R cloned-bookmarks-rev bookmarks
311 $ hg -R cloned-bookmarks-rev bookmarks
312 X2 1:925d80f479bb
312 X2 1:925d80f479bb
313
313
314 create bundle with two heads
314 create bundle with two heads
315
315
316 $ hg clone . tobundle
316 $ hg clone . tobundle
317 updating to branch default
317 updating to branch default
318 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 $ echo x > tobundle/x
319 $ echo x > tobundle/x
320 $ hg -R tobundle add tobundle/x
320 $ hg -R tobundle add tobundle/x
321 $ hg -R tobundle commit -m'x'
321 $ hg -R tobundle commit -m'x'
322 $ hg -R tobundle update -r -2
322 $ hg -R tobundle update -r -2
323 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
323 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
324 $ echo y > tobundle/y
324 $ echo y > tobundle/y
325 $ hg -R tobundle branch test
325 $ hg -R tobundle branch test
326 marked working directory as branch test
326 marked working directory as branch test
327 (branches are permanent and global, did you want a bookmark?)
327 $ hg -R tobundle add tobundle/y
328 $ hg -R tobundle add tobundle/y
328 $ hg -R tobundle commit -m'y'
329 $ hg -R tobundle commit -m'y'
329 $ hg -R tobundle bundle tobundle.hg
330 $ hg -R tobundle bundle tobundle.hg
330 searching for changes
331 searching for changes
331 2 changesets found
332 2 changesets found
332 $ hg unbundle tobundle.hg
333 $ hg unbundle tobundle.hg
333 adding changesets
334 adding changesets
334 adding manifests
335 adding manifests
335 adding file changes
336 adding file changes
336 added 2 changesets with 2 changes to 2 files (+1 heads)
337 added 2 changesets with 2 changes to 2 files (+1 heads)
337 (run 'hg heads' to see heads, 'hg merge' to merge)
338 (run 'hg heads' to see heads, 'hg merge' to merge)
338 $ hg update
339 $ hg update
339 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 $ hg bookmarks
341 $ hg bookmarks
341 X2 1:925d80f479bb
342 X2 1:925d80f479bb
342 Y 2:db815d6d32e6
343 Y 2:db815d6d32e6
343 * Z 3:125c9a1d6df6
344 * Z 3:125c9a1d6df6
344 x y 2:db815d6d32e6
345 x y 2:db815d6d32e6
345
346
346 test wrongly formated bookmark
347 test wrongly formated bookmark
347
348
348 $ echo '' >> .hg/bookmarks
349 $ echo '' >> .hg/bookmarks
349 $ hg bookmarks
350 $ hg bookmarks
350 X2 1:925d80f479bb
351 X2 1:925d80f479bb
351 Y 2:db815d6d32e6
352 Y 2:db815d6d32e6
352 * Z 3:125c9a1d6df6
353 * Z 3:125c9a1d6df6
353 x y 2:db815d6d32e6
354 x y 2:db815d6d32e6
354 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
355 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
355 $ hg bookmarks
356 $ hg bookmarks
356 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
357 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
357 X2 1:925d80f479bb
358 X2 1:925d80f479bb
358 Y 2:db815d6d32e6
359 Y 2:db815d6d32e6
359 * Z 3:125c9a1d6df6
360 * Z 3:125c9a1d6df6
360 x y 2:db815d6d32e6
361 x y 2:db815d6d32e6
361
362
@@ -1,126 +1,132 b''
1 test branch selection options
1 test branch selection options
2
2
3 $ hg init branch
3 $ hg init branch
4 $ cd branch
4 $ cd branch
5 $ hg branch a
5 $ hg branch a
6 marked working directory as branch a
6 marked working directory as branch a
7 (branches are permanent and global, did you want a bookmark?)
7 $ echo a > foo
8 $ echo a > foo
8 $ hg ci -d '0 0' -Ama
9 $ hg ci -d '0 0' -Ama
9 adding foo
10 adding foo
10 $ echo a2 > foo
11 $ echo a2 > foo
11 $ hg ci -d '0 0' -ma2
12 $ hg ci -d '0 0' -ma2
12 $ hg up 0
13 $ hg up 0
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 $ hg branch c
15 $ hg branch c
15 marked working directory as branch c
16 marked working directory as branch c
17 (branches are permanent and global, did you want a bookmark?)
16 $ echo c > foo
18 $ echo c > foo
17 $ hg ci -d '0 0' -mc
19 $ hg ci -d '0 0' -mc
18 $ hg tag -l z
20 $ hg tag -l z
19 $ cd ..
21 $ cd ..
20 $ hg clone -r 0 branch branch2
22 $ hg clone -r 0 branch branch2
21 adding changesets
23 adding changesets
22 adding manifests
24 adding manifests
23 adding file changes
25 adding file changes
24 added 1 changesets with 1 changes to 1 files
26 added 1 changesets with 1 changes to 1 files
25 updating to branch a
27 updating to branch a
26 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 $ cd branch2
29 $ cd branch2
28 $ hg up 0
30 $ hg up 0
29 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
31 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 $ hg branch b
32 $ hg branch b
31 marked working directory as branch b
33 marked working directory as branch b
34 (branches are permanent and global, did you want a bookmark?)
32 $ echo b > foo
35 $ echo b > foo
33 $ hg ci -d '0 0' -mb
36 $ hg ci -d '0 0' -mb
34 $ hg up 0
37 $ hg up 0
35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 $ hg --encoding utf-8 branch æ
39 $ hg --encoding utf-8 branch æ
37 marked working directory as branch \xc3\xa6 (esc)
40 marked working directory as branch \xc3\xa6 (esc)
41 (branches are permanent and global, did you want a bookmark?)
38 $ echo ae1 > foo
42 $ echo ae1 > foo
39 $ hg ci -d '0 0' -mae1
43 $ hg ci -d '0 0' -mae1
40 $ hg up 0
44 $ hg up 0
41 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 $ hg --encoding utf-8 branch -f æ
46 $ hg --encoding utf-8 branch -f æ
43 marked working directory as branch \xc3\xa6 (esc)
47 marked working directory as branch \xc3\xa6 (esc)
48 (branches are permanent and global, did you want a bookmark?)
44 $ echo ae2 > foo
49 $ echo ae2 > foo
45 $ hg ci -d '0 0' -mae2
50 $ hg ci -d '0 0' -mae2
46 created new head
51 created new head
47 $ hg up 0
52 $ hg up 0
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
53 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 $ hg branch -f b
54 $ hg branch -f b
50 marked working directory as branch b
55 marked working directory as branch b
56 (branches are permanent and global, did you want a bookmark?)
51 $ echo b2 > foo
57 $ echo b2 > foo
52 $ hg ci -d '0 0' -mb2
58 $ hg ci -d '0 0' -mb2
53 created new head
59 created new head
54
60
55 unknown branch and fallback
61 unknown branch and fallback
56
62
57 $ hg in -qbz
63 $ hg in -qbz
58 abort: unknown branch 'z'!
64 abort: unknown branch 'z'!
59 [255]
65 [255]
60 $ hg in -q ../branch#z
66 $ hg in -q ../branch#z
61 2:f25d57ab0566
67 2:f25d57ab0566
62 $ hg out -qbz
68 $ hg out -qbz
63 abort: unknown branch 'z'!
69 abort: unknown branch 'z'!
64 [255]
70 [255]
65
71
66 in rev c branch a
72 in rev c branch a
67
73
68 $ hg in -qr c ../branch#a
74 $ hg in -qr c ../branch#a
69 1:dd6e60a716c6
75 1:dd6e60a716c6
70 2:f25d57ab0566
76 2:f25d57ab0566
71 $ hg in -qr c -b a
77 $ hg in -qr c -b a
72 1:dd6e60a716c6
78 1:dd6e60a716c6
73 2:f25d57ab0566
79 2:f25d57ab0566
74
80
75 out branch .
81 out branch .
76
82
77 $ hg out -q ../branch#.
83 $ hg out -q ../branch#.
78 1:b84708d77ab7
84 1:b84708d77ab7
79 4:65511d0e2b55
85 4:65511d0e2b55
80 $ hg out -q -b .
86 $ hg out -q -b .
81 1:b84708d77ab7
87 1:b84708d77ab7
82 4:65511d0e2b55
88 4:65511d0e2b55
83
89
84 out branch . non-ascii
90 out branch . non-ascii
85
91
86 $ hg --encoding utf-8 up æ
92 $ hg --encoding utf-8 up æ
87 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 $ hg --encoding latin1 out -q ../branch#.
94 $ hg --encoding latin1 out -q ../branch#.
89 2:df5a44224d4e
95 2:df5a44224d4e
90 3:4f4a5125ca10
96 3:4f4a5125ca10
91 $ hg --encoding latin1 out -q -b .
97 $ hg --encoding latin1 out -q -b .
92 2:df5a44224d4e
98 2:df5a44224d4e
93 3:4f4a5125ca10
99 3:4f4a5125ca10
94
100
95 clone branch b
101 clone branch b
96
102
97 $ cd ..
103 $ cd ..
98 $ hg clone branch2#b branch3
104 $ hg clone branch2#b branch3
99 adding changesets
105 adding changesets
100 adding manifests
106 adding manifests
101 adding file changes
107 adding file changes
102 added 3 changesets with 3 changes to 1 files (+1 heads)
108 added 3 changesets with 3 changes to 1 files (+1 heads)
103 updating to branch b
109 updating to branch b
104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
110 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 $ hg -q -R branch3 heads b
111 $ hg -q -R branch3 heads b
106 2:65511d0e2b55
112 2:65511d0e2b55
107 1:b84708d77ab7
113 1:b84708d77ab7
108 $ hg -q -R branch3 parents
114 $ hg -q -R branch3 parents
109 2:65511d0e2b55
115 2:65511d0e2b55
110 $ rm -rf branch3
116 $ rm -rf branch3
111
117
112 clone rev a branch b
118 clone rev a branch b
113
119
114 $ hg clone -r a branch2#b branch3
120 $ hg clone -r a branch2#b branch3
115 adding changesets
121 adding changesets
116 adding manifests
122 adding manifests
117 adding file changes
123 adding file changes
118 added 3 changesets with 3 changes to 1 files (+1 heads)
124 added 3 changesets with 3 changes to 1 files (+1 heads)
119 updating to branch a
125 updating to branch a
120 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 $ hg -q -R branch3 heads b
127 $ hg -q -R branch3 heads b
122 2:65511d0e2b55
128 2:65511d0e2b55
123 1:b84708d77ab7
129 1:b84708d77ab7
124 $ hg -q -R branch3 parents
130 $ hg -q -R branch3 parents
125 0:5b65ba7c951d
131 0:5b65ba7c951d
126 $ rm -rf branch3
132 $ rm -rf branch3
@@ -1,62 +1,63 b''
1 Initial setup.
1 Initial setup.
2
2
3 $ hg init repo
3 $ hg init repo
4 $ cd repo
4 $ cd repo
5 $ touch thefile
5 $ touch thefile
6 $ hg ci -A -m 'Initial commit.'
6 $ hg ci -A -m 'Initial commit.'
7 adding thefile
7 adding thefile
8
8
9 Create a tag.
9 Create a tag.
10
10
11 $ hg tag branchortag
11 $ hg tag branchortag
12
12
13 Create a branch with the same name as the tag.
13 Create a branch with the same name as the tag.
14
14
15 $ hg branch branchortag
15 $ hg branch branchortag
16 marked working directory as branch branchortag
16 marked working directory as branch branchortag
17 (branches are permanent and global, did you want a bookmark?)
17 $ hg ci -m 'Create a branch with the same name as a tag.'
18 $ hg ci -m 'Create a branch with the same name as a tag.'
18
19
19 This is what we have:
20 This is what we have:
20
21
21 $ hg log
22 $ hg log
22 changeset: 2:10519b3f489a
23 changeset: 2:10519b3f489a
23 branch: branchortag
24 branch: branchortag
24 tag: tip
25 tag: tip
25 user: test
26 user: test
26 date: Thu Jan 01 00:00:00 1970 +0000
27 date: Thu Jan 01 00:00:00 1970 +0000
27 summary: Create a branch with the same name as a tag.
28 summary: Create a branch with the same name as a tag.
28
29
29 changeset: 1:2635c45ca99b
30 changeset: 1:2635c45ca99b
30 user: test
31 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
32 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: Added tag branchortag for changeset f57387372b5d
33 summary: Added tag branchortag for changeset f57387372b5d
33
34
34 changeset: 0:f57387372b5d
35 changeset: 0:f57387372b5d
35 tag: branchortag
36 tag: branchortag
36 user: test
37 user: test
37 date: Thu Jan 01 00:00:00 1970 +0000
38 date: Thu Jan 01 00:00:00 1970 +0000
38 summary: Initial commit.
39 summary: Initial commit.
39
40
40 Update to the tag:
41 Update to the tag:
41
42
42 $ hg up 'tag(branchortag)'
43 $ hg up 'tag(branchortag)'
43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 $ hg parents
45 $ hg parents
45 changeset: 0:f57387372b5d
46 changeset: 0:f57387372b5d
46 tag: branchortag
47 tag: branchortag
47 user: test
48 user: test
48 date: Thu Jan 01 00:00:00 1970 +0000
49 date: Thu Jan 01 00:00:00 1970 +0000
49 summary: Initial commit.
50 summary: Initial commit.
50
51
51 Updating to the branch:
52 Updating to the branch:
52
53
53 $ hg up 'branch(branchortag)'
54 $ hg up 'branch(branchortag)'
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 $ hg parents
56 $ hg parents
56 changeset: 2:10519b3f489a
57 changeset: 2:10519b3f489a
57 branch: branchortag
58 branch: branchortag
58 tag: tip
59 tag: tip
59 user: test
60 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
61 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: Create a branch with the same name as a tag.
62 summary: Create a branch with the same name as a tag.
62
63
@@ -1,400 +1,405 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo 'root' >root
3 $ echo 'root' >root
4 $ hg add root
4 $ hg add root
5 $ hg commit -d '0 0' -m "Adding root node"
5 $ hg commit -d '0 0' -m "Adding root node"
6
6
7 $ echo 'a' >a
7 $ echo 'a' >a
8 $ hg add a
8 $ hg add a
9 $ hg branch a
9 $ hg branch a
10 marked working directory as branch a
10 marked working directory as branch a
11 (branches are permanent and global, did you want a bookmark?)
11 $ hg commit -d '1 0' -m "Adding a branch"
12 $ hg commit -d '1 0' -m "Adding a branch"
12
13
13 $ hg branch q
14 $ hg branch q
14 marked working directory as branch q
15 marked working directory as branch q
16 (branches are permanent and global, did you want a bookmark?)
15 $ echo 'aa' >a
17 $ echo 'aa' >a
16 $ hg branch -C
18 $ hg branch -C
17 reset working directory to branch a
19 reset working directory to branch a
18 $ hg commit -d '2 0' -m "Adding to a branch"
20 $ hg commit -d '2 0' -m "Adding to a branch"
19
21
20 $ hg update -C 0
22 $ hg update -C 0
21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
23 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 $ echo 'b' >b
24 $ echo 'b' >b
23 $ hg add b
25 $ hg add b
24 $ hg branch b
26 $ hg branch b
25 marked working directory as branch b
27 marked working directory as branch b
28 (branches are permanent and global, did you want a bookmark?)
26 $ hg commit -d '2 0' -m "Adding b branch"
29 $ hg commit -d '2 0' -m "Adding b branch"
27
30
28 $ echo 'bh1' >bh1
31 $ echo 'bh1' >bh1
29 $ hg add bh1
32 $ hg add bh1
30 $ hg commit -d '3 0' -m "Adding b branch head 1"
33 $ hg commit -d '3 0' -m "Adding b branch head 1"
31
34
32 $ hg update -C 2
35 $ hg update -C 2
33 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
36 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 $ echo 'bh2' >bh2
37 $ echo 'bh2' >bh2
35 $ hg add bh2
38 $ hg add bh2
36 $ hg commit -d '4 0' -m "Adding b branch head 2"
39 $ hg commit -d '4 0' -m "Adding b branch head 2"
37
40
38 $ echo 'c' >c
41 $ echo 'c' >c
39 $ hg add c
42 $ hg add c
40 $ hg branch c
43 $ hg branch c
41 marked working directory as branch c
44 marked working directory as branch c
45 (branches are permanent and global, did you want a bookmark?)
42 $ hg commit -d '5 0' -m "Adding c branch"
46 $ hg commit -d '5 0' -m "Adding c branch"
43
47
44 $ hg branch tip
48 $ hg branch tip
45 abort: the name 'tip' is reserved
49 abort: the name 'tip' is reserved
46 [255]
50 [255]
47 $ hg branch null
51 $ hg branch null
48 abort: the name 'null' is reserved
52 abort: the name 'null' is reserved
49 [255]
53 [255]
50 $ hg branch .
54 $ hg branch .
51 abort: the name '.' is reserved
55 abort: the name '.' is reserved
52 [255]
56 [255]
53
57
54 $ echo 'd' >d
58 $ echo 'd' >d
55 $ hg add d
59 $ hg add d
56 $ hg branch 'a branch name much longer than the default justification used by branches'
60 $ hg branch 'a branch name much longer than the default justification used by branches'
57 marked working directory as branch a branch name much longer than the default justification used by branches
61 marked working directory as branch a branch name much longer than the default justification used by branches
62 (branches are permanent and global, did you want a bookmark?)
58 $ hg commit -d '6 0' -m "Adding d branch"
63 $ hg commit -d '6 0' -m "Adding d branch"
59
64
60 $ hg branches
65 $ hg branches
61 a branch name much longer than the default justification used by branches 7:10ff5895aa57
66 a branch name much longer than the default justification used by branches 7:10ff5895aa57
62 b 4:aee39cd168d0
67 b 4:aee39cd168d0
63 c 6:589736a22561 (inactive)
68 c 6:589736a22561 (inactive)
64 a 5:d8cbc61dbaa6 (inactive)
69 a 5:d8cbc61dbaa6 (inactive)
65 default 0:19709c5a4e75 (inactive)
70 default 0:19709c5a4e75 (inactive)
66
71
67 -------
72 -------
68
73
69 $ hg branches -a
74 $ hg branches -a
70 a branch name much longer than the default justification used by branches 7:10ff5895aa57
75 a branch name much longer than the default justification used by branches 7:10ff5895aa57
71 b 4:aee39cd168d0
76 b 4:aee39cd168d0
72
77
73 --- Branch a
78 --- Branch a
74
79
75 $ hg log -b a
80 $ hg log -b a
76 changeset: 5:d8cbc61dbaa6
81 changeset: 5:d8cbc61dbaa6
77 branch: a
82 branch: a
78 parent: 2:881fe2b92ad0
83 parent: 2:881fe2b92ad0
79 user: test
84 user: test
80 date: Thu Jan 01 00:00:04 1970 +0000
85 date: Thu Jan 01 00:00:04 1970 +0000
81 summary: Adding b branch head 2
86 summary: Adding b branch head 2
82
87
83 changeset: 2:881fe2b92ad0
88 changeset: 2:881fe2b92ad0
84 branch: a
89 branch: a
85 user: test
90 user: test
86 date: Thu Jan 01 00:00:02 1970 +0000
91 date: Thu Jan 01 00:00:02 1970 +0000
87 summary: Adding to a branch
92 summary: Adding to a branch
88
93
89 changeset: 1:dd6b440dd85a
94 changeset: 1:dd6b440dd85a
90 branch: a
95 branch: a
91 user: test
96 user: test
92 date: Thu Jan 01 00:00:01 1970 +0000
97 date: Thu Jan 01 00:00:01 1970 +0000
93 summary: Adding a branch
98 summary: Adding a branch
94
99
95
100
96 ---- Branch b
101 ---- Branch b
97
102
98 $ hg log -b b
103 $ hg log -b b
99 changeset: 4:aee39cd168d0
104 changeset: 4:aee39cd168d0
100 branch: b
105 branch: b
101 user: test
106 user: test
102 date: Thu Jan 01 00:00:03 1970 +0000
107 date: Thu Jan 01 00:00:03 1970 +0000
103 summary: Adding b branch head 1
108 summary: Adding b branch head 1
104
109
105 changeset: 3:ac22033332d1
110 changeset: 3:ac22033332d1
106 branch: b
111 branch: b
107 parent: 0:19709c5a4e75
112 parent: 0:19709c5a4e75
108 user: test
113 user: test
109 date: Thu Jan 01 00:00:02 1970 +0000
114 date: Thu Jan 01 00:00:02 1970 +0000
110 summary: Adding b branch
115 summary: Adding b branch
111
116
112
117
113 ---- going to test branch closing
118 ---- going to test branch closing
114
119
115 $ hg branches
120 $ hg branches
116 a branch name much longer than the default justification used by branches 7:10ff5895aa57
121 a branch name much longer than the default justification used by branches 7:10ff5895aa57
117 b 4:aee39cd168d0
122 b 4:aee39cd168d0
118 c 6:589736a22561 (inactive)
123 c 6:589736a22561 (inactive)
119 a 5:d8cbc61dbaa6 (inactive)
124 a 5:d8cbc61dbaa6 (inactive)
120 default 0:19709c5a4e75 (inactive)
125 default 0:19709c5a4e75 (inactive)
121 $ hg up -C b
126 $ hg up -C b
122 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
127 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
123 $ echo 'xxx1' >> b
128 $ echo 'xxx1' >> b
124 $ hg commit -d '7 0' -m 'adding cset to branch b'
129 $ hg commit -d '7 0' -m 'adding cset to branch b'
125 $ hg up -C aee39cd168d0
130 $ hg up -C aee39cd168d0
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 $ echo 'xxx2' >> b
132 $ echo 'xxx2' >> b
128 $ hg commit -d '8 0' -m 'adding head to branch b'
133 $ hg commit -d '8 0' -m 'adding head to branch b'
129 created new head
134 created new head
130 $ echo 'xxx3' >> b
135 $ echo 'xxx3' >> b
131 $ hg commit -d '9 0' -m 'adding another cset to branch b'
136 $ hg commit -d '9 0' -m 'adding another cset to branch b'
132 $ hg branches
137 $ hg branches
133 b 10:bfbe841b666e
138 b 10:bfbe841b666e
134 a branch name much longer than the default justification used by branches 7:10ff5895aa57
139 a branch name much longer than the default justification used by branches 7:10ff5895aa57
135 c 6:589736a22561 (inactive)
140 c 6:589736a22561 (inactive)
136 a 5:d8cbc61dbaa6 (inactive)
141 a 5:d8cbc61dbaa6 (inactive)
137 default 0:19709c5a4e75 (inactive)
142 default 0:19709c5a4e75 (inactive)
138 $ hg heads --closed
143 $ hg heads --closed
139 changeset: 10:bfbe841b666e
144 changeset: 10:bfbe841b666e
140 branch: b
145 branch: b
141 tag: tip
146 tag: tip
142 user: test
147 user: test
143 date: Thu Jan 01 00:00:09 1970 +0000
148 date: Thu Jan 01 00:00:09 1970 +0000
144 summary: adding another cset to branch b
149 summary: adding another cset to branch b
145
150
146 changeset: 8:eebb944467c9
151 changeset: 8:eebb944467c9
147 branch: b
152 branch: b
148 parent: 4:aee39cd168d0
153 parent: 4:aee39cd168d0
149 user: test
154 user: test
150 date: Thu Jan 01 00:00:07 1970 +0000
155 date: Thu Jan 01 00:00:07 1970 +0000
151 summary: adding cset to branch b
156 summary: adding cset to branch b
152
157
153 changeset: 7:10ff5895aa57
158 changeset: 7:10ff5895aa57
154 branch: a branch name much longer than the default justification used by branches
159 branch: a branch name much longer than the default justification used by branches
155 user: test
160 user: test
156 date: Thu Jan 01 00:00:06 1970 +0000
161 date: Thu Jan 01 00:00:06 1970 +0000
157 summary: Adding d branch
162 summary: Adding d branch
158
163
159 changeset: 6:589736a22561
164 changeset: 6:589736a22561
160 branch: c
165 branch: c
161 user: test
166 user: test
162 date: Thu Jan 01 00:00:05 1970 +0000
167 date: Thu Jan 01 00:00:05 1970 +0000
163 summary: Adding c branch
168 summary: Adding c branch
164
169
165 changeset: 5:d8cbc61dbaa6
170 changeset: 5:d8cbc61dbaa6
166 branch: a
171 branch: a
167 parent: 2:881fe2b92ad0
172 parent: 2:881fe2b92ad0
168 user: test
173 user: test
169 date: Thu Jan 01 00:00:04 1970 +0000
174 date: Thu Jan 01 00:00:04 1970 +0000
170 summary: Adding b branch head 2
175 summary: Adding b branch head 2
171
176
172 changeset: 0:19709c5a4e75
177 changeset: 0:19709c5a4e75
173 user: test
178 user: test
174 date: Thu Jan 01 00:00:00 1970 +0000
179 date: Thu Jan 01 00:00:00 1970 +0000
175 summary: Adding root node
180 summary: Adding root node
176
181
177 $ hg heads
182 $ hg heads
178 changeset: 10:bfbe841b666e
183 changeset: 10:bfbe841b666e
179 branch: b
184 branch: b
180 tag: tip
185 tag: tip
181 user: test
186 user: test
182 date: Thu Jan 01 00:00:09 1970 +0000
187 date: Thu Jan 01 00:00:09 1970 +0000
183 summary: adding another cset to branch b
188 summary: adding another cset to branch b
184
189
185 changeset: 8:eebb944467c9
190 changeset: 8:eebb944467c9
186 branch: b
191 branch: b
187 parent: 4:aee39cd168d0
192 parent: 4:aee39cd168d0
188 user: test
193 user: test
189 date: Thu Jan 01 00:00:07 1970 +0000
194 date: Thu Jan 01 00:00:07 1970 +0000
190 summary: adding cset to branch b
195 summary: adding cset to branch b
191
196
192 changeset: 7:10ff5895aa57
197 changeset: 7:10ff5895aa57
193 branch: a branch name much longer than the default justification used by branches
198 branch: a branch name much longer than the default justification used by branches
194 user: test
199 user: test
195 date: Thu Jan 01 00:00:06 1970 +0000
200 date: Thu Jan 01 00:00:06 1970 +0000
196 summary: Adding d branch
201 summary: Adding d branch
197
202
198 changeset: 6:589736a22561
203 changeset: 6:589736a22561
199 branch: c
204 branch: c
200 user: test
205 user: test
201 date: Thu Jan 01 00:00:05 1970 +0000
206 date: Thu Jan 01 00:00:05 1970 +0000
202 summary: Adding c branch
207 summary: Adding c branch
203
208
204 changeset: 5:d8cbc61dbaa6
209 changeset: 5:d8cbc61dbaa6
205 branch: a
210 branch: a
206 parent: 2:881fe2b92ad0
211 parent: 2:881fe2b92ad0
207 user: test
212 user: test
208 date: Thu Jan 01 00:00:04 1970 +0000
213 date: Thu Jan 01 00:00:04 1970 +0000
209 summary: Adding b branch head 2
214 summary: Adding b branch head 2
210
215
211 changeset: 0:19709c5a4e75
216 changeset: 0:19709c5a4e75
212 user: test
217 user: test
213 date: Thu Jan 01 00:00:00 1970 +0000
218 date: Thu Jan 01 00:00:00 1970 +0000
214 summary: Adding root node
219 summary: Adding root node
215
220
216 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
221 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
217 $ hg branches -a
222 $ hg branches -a
218 b 8:eebb944467c9
223 b 8:eebb944467c9
219 a branch name much longer than the default justification used by branches 7:10ff5895aa57
224 a branch name much longer than the default justification used by branches 7:10ff5895aa57
220 $ hg up -C b
225 $ hg up -C b
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
227 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
223
228
224 --- b branch should be inactive
229 --- b branch should be inactive
225
230
226 $ hg branches
231 $ hg branches
227 a branch name much longer than the default justification used by branches 7:10ff5895aa57
232 a branch name much longer than the default justification used by branches 7:10ff5895aa57
228 c 6:589736a22561 (inactive)
233 c 6:589736a22561 (inactive)
229 a 5:d8cbc61dbaa6 (inactive)
234 a 5:d8cbc61dbaa6 (inactive)
230 default 0:19709c5a4e75 (inactive)
235 default 0:19709c5a4e75 (inactive)
231 $ hg branches -c
236 $ hg branches -c
232 a branch name much longer than the default justification used by branches 7:10ff5895aa57
237 a branch name much longer than the default justification used by branches 7:10ff5895aa57
233 b 12:e3d49c0575d8 (closed)
238 b 12:e3d49c0575d8 (closed)
234 c 6:589736a22561 (inactive)
239 c 6:589736a22561 (inactive)
235 a 5:d8cbc61dbaa6 (inactive)
240 a 5:d8cbc61dbaa6 (inactive)
236 default 0:19709c5a4e75 (inactive)
241 default 0:19709c5a4e75 (inactive)
237 $ hg branches -a
242 $ hg branches -a
238 a branch name much longer than the default justification used by branches 7:10ff5895aa57
243 a branch name much longer than the default justification used by branches 7:10ff5895aa57
239 $ hg heads b
244 $ hg heads b
240 no open branch heads found on branches b
245 no open branch heads found on branches b
241 [1]
246 [1]
242 $ hg heads --closed b
247 $ hg heads --closed b
243 changeset: 12:e3d49c0575d8
248 changeset: 12:e3d49c0575d8
244 branch: b
249 branch: b
245 tag: tip
250 tag: tip
246 parent: 8:eebb944467c9
251 parent: 8:eebb944467c9
247 user: test
252 user: test
248 date: Thu Jan 01 00:00:09 1970 +0000
253 date: Thu Jan 01 00:00:09 1970 +0000
249 summary: close this part branch too
254 summary: close this part branch too
250
255
251 changeset: 11:d3f163457ebf
256 changeset: 11:d3f163457ebf
252 branch: b
257 branch: b
253 user: test
258 user: test
254 date: Thu Jan 01 00:00:09 1970 +0000
259 date: Thu Jan 01 00:00:09 1970 +0000
255 summary: prune bad branch
260 summary: prune bad branch
256
261
257 $ echo 'xxx4' >> b
262 $ echo 'xxx4' >> b
258 $ hg commit -d '9 0' -m 'reopen branch with a change'
263 $ hg commit -d '9 0' -m 'reopen branch with a change'
259 reopening closed branch head 12
264 reopening closed branch head 12
260
265
261 --- branch b is back in action
266 --- branch b is back in action
262
267
263 $ hg branches -a
268 $ hg branches -a
264 b 13:e23b5505d1ad
269 b 13:e23b5505d1ad
265 a branch name much longer than the default justification used by branches 7:10ff5895aa57
270 a branch name much longer than the default justification used by branches 7:10ff5895aa57
266
271
267 ---- test heads listings
272 ---- test heads listings
268
273
269 $ hg heads
274 $ hg heads
270 changeset: 13:e23b5505d1ad
275 changeset: 13:e23b5505d1ad
271 branch: b
276 branch: b
272 tag: tip
277 tag: tip
273 user: test
278 user: test
274 date: Thu Jan 01 00:00:09 1970 +0000
279 date: Thu Jan 01 00:00:09 1970 +0000
275 summary: reopen branch with a change
280 summary: reopen branch with a change
276
281
277 changeset: 7:10ff5895aa57
282 changeset: 7:10ff5895aa57
278 branch: a branch name much longer than the default justification used by branches
283 branch: a branch name much longer than the default justification used by branches
279 user: test
284 user: test
280 date: Thu Jan 01 00:00:06 1970 +0000
285 date: Thu Jan 01 00:00:06 1970 +0000
281 summary: Adding d branch
286 summary: Adding d branch
282
287
283 changeset: 6:589736a22561
288 changeset: 6:589736a22561
284 branch: c
289 branch: c
285 user: test
290 user: test
286 date: Thu Jan 01 00:00:05 1970 +0000
291 date: Thu Jan 01 00:00:05 1970 +0000
287 summary: Adding c branch
292 summary: Adding c branch
288
293
289 changeset: 5:d8cbc61dbaa6
294 changeset: 5:d8cbc61dbaa6
290 branch: a
295 branch: a
291 parent: 2:881fe2b92ad0
296 parent: 2:881fe2b92ad0
292 user: test
297 user: test
293 date: Thu Jan 01 00:00:04 1970 +0000
298 date: Thu Jan 01 00:00:04 1970 +0000
294 summary: Adding b branch head 2
299 summary: Adding b branch head 2
295
300
296 changeset: 0:19709c5a4e75
301 changeset: 0:19709c5a4e75
297 user: test
302 user: test
298 date: Thu Jan 01 00:00:00 1970 +0000
303 date: Thu Jan 01 00:00:00 1970 +0000
299 summary: Adding root node
304 summary: Adding root node
300
305
301
306
302 branch default
307 branch default
303
308
304 $ hg heads default
309 $ hg heads default
305 changeset: 0:19709c5a4e75
310 changeset: 0:19709c5a4e75
306 user: test
311 user: test
307 date: Thu Jan 01 00:00:00 1970 +0000
312 date: Thu Jan 01 00:00:00 1970 +0000
308 summary: Adding root node
313 summary: Adding root node
309
314
310
315
311 branch a
316 branch a
312
317
313 $ hg heads a
318 $ hg heads a
314 changeset: 5:d8cbc61dbaa6
319 changeset: 5:d8cbc61dbaa6
315 branch: a
320 branch: a
316 parent: 2:881fe2b92ad0
321 parent: 2:881fe2b92ad0
317 user: test
322 user: test
318 date: Thu Jan 01 00:00:04 1970 +0000
323 date: Thu Jan 01 00:00:04 1970 +0000
319 summary: Adding b branch head 2
324 summary: Adding b branch head 2
320
325
321 $ hg heads --active a
326 $ hg heads --active a
322 no open branch heads found on branches a
327 no open branch heads found on branches a
323 [1]
328 [1]
324
329
325 branch b
330 branch b
326
331
327 $ hg heads b
332 $ hg heads b
328 changeset: 13:e23b5505d1ad
333 changeset: 13:e23b5505d1ad
329 branch: b
334 branch: b
330 tag: tip
335 tag: tip
331 user: test
336 user: test
332 date: Thu Jan 01 00:00:09 1970 +0000
337 date: Thu Jan 01 00:00:09 1970 +0000
333 summary: reopen branch with a change
338 summary: reopen branch with a change
334
339
335 $ hg heads --closed b
340 $ hg heads --closed b
336 changeset: 13:e23b5505d1ad
341 changeset: 13:e23b5505d1ad
337 branch: b
342 branch: b
338 tag: tip
343 tag: tip
339 user: test
344 user: test
340 date: Thu Jan 01 00:00:09 1970 +0000
345 date: Thu Jan 01 00:00:09 1970 +0000
341 summary: reopen branch with a change
346 summary: reopen branch with a change
342
347
343 changeset: 11:d3f163457ebf
348 changeset: 11:d3f163457ebf
344 branch: b
349 branch: b
345 user: test
350 user: test
346 date: Thu Jan 01 00:00:09 1970 +0000
351 date: Thu Jan 01 00:00:09 1970 +0000
347 summary: prune bad branch
352 summary: prune bad branch
348
353
349 default branch colors:
354 default branch colors:
350
355
351 $ echo "[extensions]" >> $HGRCPATH
356 $ echo "[extensions]" >> $HGRCPATH
352 $ echo "color =" >> $HGRCPATH
357 $ echo "color =" >> $HGRCPATH
353 $ echo "[color]" >> $HGRCPATH
358 $ echo "[color]" >> $HGRCPATH
354 $ echo "mode = ansi" >> $HGRCPATH
359 $ echo "mode = ansi" >> $HGRCPATH
355
360
356 $ hg up -C c
361 $ hg up -C c
357 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
362 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
358 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
363 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
359 $ hg up -C b
364 $ hg up -C b
360 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
365 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
361 $ hg branches --color=always
366 $ hg branches --color=always
362 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
367 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
363 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
368 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
364 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
369 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
365 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
370 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
366
371
367 default closed branch color:
372 default closed branch color:
368
373
369 $ hg branches --color=always --closed
374 $ hg branches --color=always --closed
370 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
375 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
371 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
376 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
372 \x1b[0;30;1mc\x1b[0m \x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
377 \x1b[0;30;1mc\x1b[0m \x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
373 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
378 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
374 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
379 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
375
380
376 $ echo "[extensions]" >> $HGRCPATH
381 $ echo "[extensions]" >> $HGRCPATH
377 $ echo "color =" >> $HGRCPATH
382 $ echo "color =" >> $HGRCPATH
378 $ echo "[color]" >> $HGRCPATH
383 $ echo "[color]" >> $HGRCPATH
379 $ echo "branches.active = green" >> $HGRCPATH
384 $ echo "branches.active = green" >> $HGRCPATH
380 $ echo "branches.closed = blue" >> $HGRCPATH
385 $ echo "branches.closed = blue" >> $HGRCPATH
381 $ echo "branches.current = red" >> $HGRCPATH
386 $ echo "branches.current = red" >> $HGRCPATH
382 $ echo "branches.inactive = magenta" >> $HGRCPATH
387 $ echo "branches.inactive = magenta" >> $HGRCPATH
383 $ echo "log.changeset = cyan" >> $HGRCPATH
388 $ echo "log.changeset = cyan" >> $HGRCPATH
384
389
385 custom branch colors:
390 custom branch colors:
386
391
387 $ hg branches --color=always
392 $ hg branches --color=always
388 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
393 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
389 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
394 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
390 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
395 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
391 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
396 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
392
397
393 custom closed branch color:
398 custom closed branch color:
394
399
395 $ hg branches --color=always --closed
400 $ hg branches --color=always --closed
396 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
401 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
397 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
402 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
398 \x1b[0;34mc\x1b[0m \x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
403 \x1b[0;34mc\x1b[0m \x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
399 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
404 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
400 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
405 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
@@ -1,103 +1,105 b''
1 $ hg init
1 $ hg init
2 $ echo foo > bar
2 $ echo foo > bar
3 $ hg commit -Am default
3 $ hg commit -Am default
4 adding bar
4 adding bar
5 $ hg up -r null
5 $ hg up -r null
6 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
6 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
7 $ hg branch mine
7 $ hg branch mine
8 marked working directory as branch mine
8 marked working directory as branch mine
9 (branches are permanent and global, did you want a bookmark?)
9 $ echo hello > world
10 $ echo hello > world
10 $ hg commit -Am hello
11 $ hg commit -Am hello
11 adding world
12 adding world
12 $ hg up -r null
13 $ hg up -r null
13 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
14 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
14 $ hg branch other
15 $ hg branch other
15 marked working directory as branch other
16 marked working directory as branch other
17 (branches are permanent and global, did you want a bookmark?)
16 $ echo good > bye
18 $ echo good > bye
17 $ hg commit -Am other
19 $ hg commit -Am other
18 adding bye
20 adding bye
19 $ hg up -r mine
21 $ hg up -r mine
20 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
21
23
22 $ hg clone -U -u . .#other ../b -r 0 -r 1 -r 2 -b other
24 $ hg clone -U -u . .#other ../b -r 0 -r 1 -r 2 -b other
23 abort: cannot specify both --noupdate and --updaterev
25 abort: cannot specify both --noupdate and --updaterev
24 [255]
26 [255]
25
27
26 $ hg clone -U .#other ../b -r 0 -r 1 -r 2 -b other
28 $ hg clone -U .#other ../b -r 0 -r 1 -r 2 -b other
27 adding changesets
29 adding changesets
28 adding manifests
30 adding manifests
29 adding file changes
31 adding file changes
30 added 3 changesets with 3 changes to 3 files (+2 heads)
32 added 3 changesets with 3 changes to 3 files (+2 heads)
31 $ rm -rf ../b
33 $ rm -rf ../b
32
34
33 $ hg clone -u . .#other ../b -r 0 -r 1 -r 2 -b other
35 $ hg clone -u . .#other ../b -r 0 -r 1 -r 2 -b other
34 adding changesets
36 adding changesets
35 adding manifests
37 adding manifests
36 adding file changes
38 adding file changes
37 added 3 changesets with 3 changes to 3 files (+2 heads)
39 added 3 changesets with 3 changes to 3 files (+2 heads)
38 updating to branch mine
40 updating to branch mine
39 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
40 $ rm -rf ../b
42 $ rm -rf ../b
41
43
42 $ hg clone -u 0 .#other ../b -r 0 -r 1 -r 2 -b other
44 $ hg clone -u 0 .#other ../b -r 0 -r 1 -r 2 -b other
43 adding changesets
45 adding changesets
44 adding manifests
46 adding manifests
45 adding file changes
47 adding file changes
46 added 3 changesets with 3 changes to 3 files (+2 heads)
48 added 3 changesets with 3 changes to 3 files (+2 heads)
47 updating to branch default
49 updating to branch default
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 $ rm -rf ../b
51 $ rm -rf ../b
50
52
51 $ hg clone -u 1 .#other ../b -r 0 -r 1 -r 2 -b other
53 $ hg clone -u 1 .#other ../b -r 0 -r 1 -r 2 -b other
52 adding changesets
54 adding changesets
53 adding manifests
55 adding manifests
54 adding file changes
56 adding file changes
55 added 3 changesets with 3 changes to 3 files (+2 heads)
57 added 3 changesets with 3 changes to 3 files (+2 heads)
56 updating to branch mine
58 updating to branch mine
57 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 $ rm -rf ../b
60 $ rm -rf ../b
59
61
60 $ hg clone -u 2 .#other ../b -r 0 -r 1 -r 2 -b other
62 $ hg clone -u 2 .#other ../b -r 0 -r 1 -r 2 -b other
61 adding changesets
63 adding changesets
62 adding manifests
64 adding manifests
63 adding file changes
65 adding file changes
64 added 3 changesets with 3 changes to 3 files (+2 heads)
66 added 3 changesets with 3 changes to 3 files (+2 heads)
65 updating to branch other
67 updating to branch other
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 $ rm -rf ../b
69 $ rm -rf ../b
68
70
69 Test -r mine ... mine is ignored:
71 Test -r mine ... mine is ignored:
70
72
71 $ hg clone -u 2 .#other ../b -r mine -r 0 -r 1 -r 2 -b other
73 $ hg clone -u 2 .#other ../b -r mine -r 0 -r 1 -r 2 -b other
72 adding changesets
74 adding changesets
73 adding manifests
75 adding manifests
74 adding file changes
76 adding file changes
75 added 3 changesets with 3 changes to 3 files (+2 heads)
77 added 3 changesets with 3 changes to 3 files (+2 heads)
76 updating to branch other
78 updating to branch other
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 $ rm -rf ../b
80 $ rm -rf ../b
79
81
80 $ hg clone .#other ../b -b default -b mine
82 $ hg clone .#other ../b -b default -b mine
81 adding changesets
83 adding changesets
82 adding manifests
84 adding manifests
83 adding file changes
85 adding file changes
84 added 3 changesets with 3 changes to 3 files (+2 heads)
86 added 3 changesets with 3 changes to 3 files (+2 heads)
85 updating to branch default
87 updating to branch default
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 $ rm -rf ../b
89 $ rm -rf ../b
88
90
89 $ hg clone .#other ../b
91 $ hg clone .#other ../b
90 adding changesets
92 adding changesets
91 adding manifests
93 adding manifests
92 adding file changes
94 adding file changes
93 added 1 changesets with 1 changes to 1 files
95 added 1 changesets with 1 changes to 1 files
94 updating to branch other
96 updating to branch other
95 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
96 $ rm -rf ../b
98 $ rm -rf ../b
97
99
98 $ hg clone -U . ../c -r 1 -r 2 > /dev/null
100 $ hg clone -U . ../c -r 1 -r 2 > /dev/null
99 $ hg clone ../c ../b
101 $ hg clone ../c ../b
100 updating to branch other
102 updating to branch other
101 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
103 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 $ rm -rf ../b ../c
104 $ rm -rf ../b ../c
103
105
@@ -1,459 +1,460 b''
1 Prepare repo a:
1 Prepare repo a:
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ echo a > a
5 $ echo a > a
6 $ hg add a
6 $ hg add a
7 $ hg commit -m test
7 $ hg commit -m test
8 $ echo first line > b
8 $ echo first line > b
9 $ hg add b
9 $ hg add b
10
10
11 Create a non-inlined filelog:
11 Create a non-inlined filelog:
12
12
13 $ python -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
13 $ python -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
15 > cat data1 >> b
15 > cat data1 >> b
16 > hg commit -m test
16 > hg commit -m test
17 > done
17 > done
18
18
19 List files in store/data (should show a 'b.d'):
19 List files in store/data (should show a 'b.d'):
20
20
21 $ for i in .hg/store/data/*; do
21 $ for i in .hg/store/data/*; do
22 > echo $i
22 > echo $i
23 > done
23 > done
24 .hg/store/data/a.i
24 .hg/store/data/a.i
25 .hg/store/data/b.d
25 .hg/store/data/b.d
26 .hg/store/data/b.i
26 .hg/store/data/b.i
27
27
28 Default operation:
28 Default operation:
29
29
30 $ hg clone . ../b
30 $ hg clone . ../b
31 updating to branch default
31 updating to branch default
32 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
32 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 $ cd ../b
33 $ cd ../b
34 $ cat a
34 $ cat a
35 a
35 a
36 $ hg verify
36 $ hg verify
37 checking changesets
37 checking changesets
38 checking manifests
38 checking manifests
39 crosschecking files in changesets and manifests
39 crosschecking files in changesets and manifests
40 checking files
40 checking files
41 2 files, 11 changesets, 11 total revisions
41 2 files, 11 changesets, 11 total revisions
42
42
43 Invalid dest '' must abort:
43 Invalid dest '' must abort:
44
44
45 $ hg clone . ''
45 $ hg clone . ''
46 abort: * (glob)
46 abort: * (glob)
47 [255]
47 [255]
48
48
49 No update, with debug option:
49 No update, with debug option:
50
50
51 $ hg --debug clone -U . ../c
51 $ hg --debug clone -U . ../c
52 linked 8 files
52 linked 8 files
53 $ cd ../c
53 $ cd ../c
54 $ cat a 2>/dev/null || echo "a not present"
54 $ cat a 2>/dev/null || echo "a not present"
55 a not present
55 a not present
56 $ hg verify
56 $ hg verify
57 checking changesets
57 checking changesets
58 checking manifests
58 checking manifests
59 crosschecking files in changesets and manifests
59 crosschecking files in changesets and manifests
60 checking files
60 checking files
61 2 files, 11 changesets, 11 total revisions
61 2 files, 11 changesets, 11 total revisions
62
62
63 Default destination:
63 Default destination:
64
64
65 $ mkdir ../d
65 $ mkdir ../d
66 $ cd ../d
66 $ cd ../d
67 $ hg clone ../a
67 $ hg clone ../a
68 destination directory: a
68 destination directory: a
69 updating to branch default
69 updating to branch default
70 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 $ cd a
71 $ cd a
72 $ hg cat a
72 $ hg cat a
73 a
73 a
74 $ cd ../..
74 $ cd ../..
75
75
76 Check that we drop the 'file:' from the path before writing the .hgrc:
76 Check that we drop the 'file:' from the path before writing the .hgrc:
77
77
78 $ hg clone file:a e
78 $ hg clone file:a e
79 updating to branch default
79 updating to branch default
80 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 $ grep 'file:' e/.hg/hgrc
81 $ grep 'file:' e/.hg/hgrc
82 [1]
82 [1]
83
83
84 Check that path aliases are expanded:
84 Check that path aliases are expanded:
85
85
86 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
86 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
87 $ hg -R f showconfig paths.default
87 $ hg -R f showconfig paths.default
88 $TESTTMP/a#0 (glob)
88 $TESTTMP/a#0 (glob)
89
89
90 Use --pull:
90 Use --pull:
91
91
92 $ hg clone --pull a g
92 $ hg clone --pull a g
93 requesting all changes
93 requesting all changes
94 adding changesets
94 adding changesets
95 adding manifests
95 adding manifests
96 adding file changes
96 adding file changes
97 added 11 changesets with 11 changes to 2 files
97 added 11 changesets with 11 changes to 2 files
98 updating to branch default
98 updating to branch default
99 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 $ hg -R g verify
100 $ hg -R g verify
101 checking changesets
101 checking changesets
102 checking manifests
102 checking manifests
103 crosschecking files in changesets and manifests
103 crosschecking files in changesets and manifests
104 checking files
104 checking files
105 2 files, 11 changesets, 11 total revisions
105 2 files, 11 changesets, 11 total revisions
106
106
107 Invalid dest '' with --pull must abort (issue2528):
107 Invalid dest '' with --pull must abort (issue2528):
108
108
109 $ hg clone --pull a ''
109 $ hg clone --pull a ''
110 abort: * (glob)
110 abort: * (glob)
111 [255]
111 [255]
112
112
113 Clone to '.':
113 Clone to '.':
114
114
115 $ mkdir h
115 $ mkdir h
116 $ cd h
116 $ cd h
117 $ hg clone ../a .
117 $ hg clone ../a .
118 updating to branch default
118 updating to branch default
119 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 $ cd ..
120 $ cd ..
121
121
122
122
123 *** Tests for option -u ***
123 *** Tests for option -u ***
124
124
125 Adding some more history to repo a:
125 Adding some more history to repo a:
126
126
127 $ cd a
127 $ cd a
128 $ hg tag ref1
128 $ hg tag ref1
129 $ echo the quick brown fox >a
129 $ echo the quick brown fox >a
130 $ hg ci -m "hacked default"
130 $ hg ci -m "hacked default"
131 $ hg up ref1
131 $ hg up ref1
132 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
132 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
133 $ hg branch stable
133 $ hg branch stable
134 marked working directory as branch stable
134 marked working directory as branch stable
135 (branches are permanent and global, did you want a bookmark?)
135 $ echo some text >a
136 $ echo some text >a
136 $ hg ci -m "starting branch stable"
137 $ hg ci -m "starting branch stable"
137 $ hg tag ref2
138 $ hg tag ref2
138 $ echo some more text >a
139 $ echo some more text >a
139 $ hg ci -m "another change for branch stable"
140 $ hg ci -m "another change for branch stable"
140 $ hg up ref2
141 $ hg up ref2
141 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
142 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
142 $ hg parents
143 $ hg parents
143 changeset: 13:e8ece76546a6
144 changeset: 13:e8ece76546a6
144 branch: stable
145 branch: stable
145 tag: ref2
146 tag: ref2
146 parent: 10:a7949464abda
147 parent: 10:a7949464abda
147 user: test
148 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
149 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: starting branch stable
150 summary: starting branch stable
150
151
151
152
152 Repo a has two heads:
153 Repo a has two heads:
153
154
154 $ hg heads
155 $ hg heads
155 changeset: 15:0aae7cf88f0d
156 changeset: 15:0aae7cf88f0d
156 branch: stable
157 branch: stable
157 tag: tip
158 tag: tip
158 user: test
159 user: test
159 date: Thu Jan 01 00:00:00 1970 +0000
160 date: Thu Jan 01 00:00:00 1970 +0000
160 summary: another change for branch stable
161 summary: another change for branch stable
161
162
162 changeset: 12:f21241060d6a
163 changeset: 12:f21241060d6a
163 user: test
164 user: test
164 date: Thu Jan 01 00:00:00 1970 +0000
165 date: Thu Jan 01 00:00:00 1970 +0000
165 summary: hacked default
166 summary: hacked default
166
167
167
168
168 $ cd ..
169 $ cd ..
169
170
170
171
171 Testing --noupdate with --updaterev (must abort):
172 Testing --noupdate with --updaterev (must abort):
172
173
173 $ hg clone --noupdate --updaterev 1 a ua
174 $ hg clone --noupdate --updaterev 1 a ua
174 abort: cannot specify both --noupdate and --updaterev
175 abort: cannot specify both --noupdate and --updaterev
175 [255]
176 [255]
176
177
177
178
178 Testing clone -u:
179 Testing clone -u:
179
180
180 $ hg clone -u . a ua
181 $ hg clone -u . a ua
181 updating to branch stable
182 updating to branch stable
182 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
183 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
183
184
184 Repo ua has both heads:
185 Repo ua has both heads:
185
186
186 $ hg -R ua heads
187 $ hg -R ua heads
187 changeset: 15:0aae7cf88f0d
188 changeset: 15:0aae7cf88f0d
188 branch: stable
189 branch: stable
189 tag: tip
190 tag: tip
190 user: test
191 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
192 date: Thu Jan 01 00:00:00 1970 +0000
192 summary: another change for branch stable
193 summary: another change for branch stable
193
194
194 changeset: 12:f21241060d6a
195 changeset: 12:f21241060d6a
195 user: test
196 user: test
196 date: Thu Jan 01 00:00:00 1970 +0000
197 date: Thu Jan 01 00:00:00 1970 +0000
197 summary: hacked default
198 summary: hacked default
198
199
199
200
200 Same revision checked out in repo a and ua:
201 Same revision checked out in repo a and ua:
201
202
202 $ hg -R a parents --template "{node|short}\n"
203 $ hg -R a parents --template "{node|short}\n"
203 e8ece76546a6
204 e8ece76546a6
204 $ hg -R ua parents --template "{node|short}\n"
205 $ hg -R ua parents --template "{node|short}\n"
205 e8ece76546a6
206 e8ece76546a6
206
207
207 $ rm -r ua
208 $ rm -r ua
208
209
209
210
210 Testing clone --pull -u:
211 Testing clone --pull -u:
211
212
212 $ hg clone --pull -u . a ua
213 $ hg clone --pull -u . a ua
213 requesting all changes
214 requesting all changes
214 adding changesets
215 adding changesets
215 adding manifests
216 adding manifests
216 adding file changes
217 adding file changes
217 added 16 changesets with 16 changes to 3 files (+1 heads)
218 added 16 changesets with 16 changes to 3 files (+1 heads)
218 updating to branch stable
219 updating to branch stable
219 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
220
221
221 Repo ua has both heads:
222 Repo ua has both heads:
222
223
223 $ hg -R ua heads
224 $ hg -R ua heads
224 changeset: 15:0aae7cf88f0d
225 changeset: 15:0aae7cf88f0d
225 branch: stable
226 branch: stable
226 tag: tip
227 tag: tip
227 user: test
228 user: test
228 date: Thu Jan 01 00:00:00 1970 +0000
229 date: Thu Jan 01 00:00:00 1970 +0000
229 summary: another change for branch stable
230 summary: another change for branch stable
230
231
231 changeset: 12:f21241060d6a
232 changeset: 12:f21241060d6a
232 user: test
233 user: test
233 date: Thu Jan 01 00:00:00 1970 +0000
234 date: Thu Jan 01 00:00:00 1970 +0000
234 summary: hacked default
235 summary: hacked default
235
236
236
237
237 Same revision checked out in repo a and ua:
238 Same revision checked out in repo a and ua:
238
239
239 $ hg -R a parents --template "{node|short}\n"
240 $ hg -R a parents --template "{node|short}\n"
240 e8ece76546a6
241 e8ece76546a6
241 $ hg -R ua parents --template "{node|short}\n"
242 $ hg -R ua parents --template "{node|short}\n"
242 e8ece76546a6
243 e8ece76546a6
243
244
244 $ rm -r ua
245 $ rm -r ua
245
246
246
247
247 Testing clone -u <branch>:
248 Testing clone -u <branch>:
248
249
249 $ hg clone -u stable a ua
250 $ hg clone -u stable a ua
250 updating to branch stable
251 updating to branch stable
251 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
252
253
253 Repo ua has both heads:
254 Repo ua has both heads:
254
255
255 $ hg -R ua heads
256 $ hg -R ua heads
256 changeset: 15:0aae7cf88f0d
257 changeset: 15:0aae7cf88f0d
257 branch: stable
258 branch: stable
258 tag: tip
259 tag: tip
259 user: test
260 user: test
260 date: Thu Jan 01 00:00:00 1970 +0000
261 date: Thu Jan 01 00:00:00 1970 +0000
261 summary: another change for branch stable
262 summary: another change for branch stable
262
263
263 changeset: 12:f21241060d6a
264 changeset: 12:f21241060d6a
264 user: test
265 user: test
265 date: Thu Jan 01 00:00:00 1970 +0000
266 date: Thu Jan 01 00:00:00 1970 +0000
266 summary: hacked default
267 summary: hacked default
267
268
268
269
269 Branch 'stable' is checked out:
270 Branch 'stable' is checked out:
270
271
271 $ hg -R ua parents
272 $ hg -R ua parents
272 changeset: 15:0aae7cf88f0d
273 changeset: 15:0aae7cf88f0d
273 branch: stable
274 branch: stable
274 tag: tip
275 tag: tip
275 user: test
276 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
277 date: Thu Jan 01 00:00:00 1970 +0000
277 summary: another change for branch stable
278 summary: another change for branch stable
278
279
279
280
280 $ rm -r ua
281 $ rm -r ua
281
282
282
283
283 Testing default checkout:
284 Testing default checkout:
284
285
285 $ hg clone a ua
286 $ hg clone a ua
286 updating to branch default
287 updating to branch default
287 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
288
289
289 Repo ua has both heads:
290 Repo ua has both heads:
290
291
291 $ hg -R ua heads
292 $ hg -R ua heads
292 changeset: 15:0aae7cf88f0d
293 changeset: 15:0aae7cf88f0d
293 branch: stable
294 branch: stable
294 tag: tip
295 tag: tip
295 user: test
296 user: test
296 date: Thu Jan 01 00:00:00 1970 +0000
297 date: Thu Jan 01 00:00:00 1970 +0000
297 summary: another change for branch stable
298 summary: another change for branch stable
298
299
299 changeset: 12:f21241060d6a
300 changeset: 12:f21241060d6a
300 user: test
301 user: test
301 date: Thu Jan 01 00:00:00 1970 +0000
302 date: Thu Jan 01 00:00:00 1970 +0000
302 summary: hacked default
303 summary: hacked default
303
304
304
305
305 Branch 'default' is checked out:
306 Branch 'default' is checked out:
306
307
307 $ hg -R ua parents
308 $ hg -R ua parents
308 changeset: 12:f21241060d6a
309 changeset: 12:f21241060d6a
309 user: test
310 user: test
310 date: Thu Jan 01 00:00:00 1970 +0000
311 date: Thu Jan 01 00:00:00 1970 +0000
311 summary: hacked default
312 summary: hacked default
312
313
313
314
314 $ rm -r ua
315 $ rm -r ua
315
316
316
317
317 Testing #<branch>:
318 Testing #<branch>:
318
319
319 $ hg clone -u . a#stable ua
320 $ hg clone -u . a#stable ua
320 adding changesets
321 adding changesets
321 adding manifests
322 adding manifests
322 adding file changes
323 adding file changes
323 added 14 changesets with 14 changes to 3 files
324 added 14 changesets with 14 changes to 3 files
324 updating to branch stable
325 updating to branch stable
325 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
326
327
327 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
328 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
328
329
329 $ hg -R ua heads
330 $ hg -R ua heads
330 changeset: 13:0aae7cf88f0d
331 changeset: 13:0aae7cf88f0d
331 branch: stable
332 branch: stable
332 tag: tip
333 tag: tip
333 user: test
334 user: test
334 date: Thu Jan 01 00:00:00 1970 +0000
335 date: Thu Jan 01 00:00:00 1970 +0000
335 summary: another change for branch stable
336 summary: another change for branch stable
336
337
337 changeset: 10:a7949464abda
338 changeset: 10:a7949464abda
338 user: test
339 user: test
339 date: Thu Jan 01 00:00:00 1970 +0000
340 date: Thu Jan 01 00:00:00 1970 +0000
340 summary: test
341 summary: test
341
342
342
343
343 Same revision checked out in repo a and ua:
344 Same revision checked out in repo a and ua:
344
345
345 $ hg -R a parents --template "{node|short}\n"
346 $ hg -R a parents --template "{node|short}\n"
346 e8ece76546a6
347 e8ece76546a6
347 $ hg -R ua parents --template "{node|short}\n"
348 $ hg -R ua parents --template "{node|short}\n"
348 e8ece76546a6
349 e8ece76546a6
349
350
350 $ rm -r ua
351 $ rm -r ua
351
352
352
353
353 Testing -u -r <branch>:
354 Testing -u -r <branch>:
354
355
355 $ hg clone -u . -r stable a ua
356 $ hg clone -u . -r stable a ua
356 adding changesets
357 adding changesets
357 adding manifests
358 adding manifests
358 adding file changes
359 adding file changes
359 added 14 changesets with 14 changes to 3 files
360 added 14 changesets with 14 changes to 3 files
360 updating to branch stable
361 updating to branch stable
361 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
362 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
362
363
363 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
364 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
364
365
365 $ hg -R ua heads
366 $ hg -R ua heads
366 changeset: 13:0aae7cf88f0d
367 changeset: 13:0aae7cf88f0d
367 branch: stable
368 branch: stable
368 tag: tip
369 tag: tip
369 user: test
370 user: test
370 date: Thu Jan 01 00:00:00 1970 +0000
371 date: Thu Jan 01 00:00:00 1970 +0000
371 summary: another change for branch stable
372 summary: another change for branch stable
372
373
373 changeset: 10:a7949464abda
374 changeset: 10:a7949464abda
374 user: test
375 user: test
375 date: Thu Jan 01 00:00:00 1970 +0000
376 date: Thu Jan 01 00:00:00 1970 +0000
376 summary: test
377 summary: test
377
378
378
379
379 Same revision checked out in repo a and ua:
380 Same revision checked out in repo a and ua:
380
381
381 $ hg -R a parents --template "{node|short}\n"
382 $ hg -R a parents --template "{node|short}\n"
382 e8ece76546a6
383 e8ece76546a6
383 $ hg -R ua parents --template "{node|short}\n"
384 $ hg -R ua parents --template "{node|short}\n"
384 e8ece76546a6
385 e8ece76546a6
385
386
386 $ rm -r ua
387 $ rm -r ua
387
388
388
389
389 Testing -r <branch>:
390 Testing -r <branch>:
390
391
391 $ hg clone -r stable a ua
392 $ hg clone -r stable a ua
392 adding changesets
393 adding changesets
393 adding manifests
394 adding manifests
394 adding file changes
395 adding file changes
395 added 14 changesets with 14 changes to 3 files
396 added 14 changesets with 14 changes to 3 files
396 updating to branch stable
397 updating to branch stable
397 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
398
399
399 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
400 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
400
401
401 $ hg -R ua heads
402 $ hg -R ua heads
402 changeset: 13:0aae7cf88f0d
403 changeset: 13:0aae7cf88f0d
403 branch: stable
404 branch: stable
404 tag: tip
405 tag: tip
405 user: test
406 user: test
406 date: Thu Jan 01 00:00:00 1970 +0000
407 date: Thu Jan 01 00:00:00 1970 +0000
407 summary: another change for branch stable
408 summary: another change for branch stable
408
409
409 changeset: 10:a7949464abda
410 changeset: 10:a7949464abda
410 user: test
411 user: test
411 date: Thu Jan 01 00:00:00 1970 +0000
412 date: Thu Jan 01 00:00:00 1970 +0000
412 summary: test
413 summary: test
413
414
414
415
415 Branch 'stable' is checked out:
416 Branch 'stable' is checked out:
416
417
417 $ hg -R ua parents
418 $ hg -R ua parents
418 changeset: 13:0aae7cf88f0d
419 changeset: 13:0aae7cf88f0d
419 branch: stable
420 branch: stable
420 tag: tip
421 tag: tip
421 user: test
422 user: test
422 date: Thu Jan 01 00:00:00 1970 +0000
423 date: Thu Jan 01 00:00:00 1970 +0000
423 summary: another change for branch stable
424 summary: another change for branch stable
424
425
425
426
426 $ rm -r ua
427 $ rm -r ua
427
428
428
429
429 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
430 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
430 iterable in addbranchrevs()
431 iterable in addbranchrevs()
431
432
432 $ cat <<EOF > simpleclone.py
433 $ cat <<EOF > simpleclone.py
433 > from mercurial import ui, hg
434 > from mercurial import ui, hg
434 > myui = ui.ui()
435 > myui = ui.ui()
435 > repo = hg.repository(myui, 'a')
436 > repo = hg.repository(myui, 'a')
436 > hg.clone(myui, {}, repo, dest="ua")
437 > hg.clone(myui, {}, repo, dest="ua")
437 > EOF
438 > EOF
438
439
439 $ python simpleclone.py
440 $ python simpleclone.py
440 updating to branch default
441 updating to branch default
441 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
442 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
442
443
443 $ rm -r ua
444 $ rm -r ua
444
445
445 $ cat <<EOF > branchclone.py
446 $ cat <<EOF > branchclone.py
446 > from mercurial import ui, hg
447 > from mercurial import ui, hg
447 > myui = ui.ui()
448 > myui = ui.ui()
448 > repo = hg.repository(myui, 'a')
449 > repo = hg.repository(myui, 'a')
449 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
450 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
450 > EOF
451 > EOF
451
452
452 $ python branchclone.py
453 $ python branchclone.py
453 adding changesets
454 adding changesets
454 adding manifests
455 adding manifests
455 adding file changes
456 adding file changes
456 added 14 changesets with 14 changes to 3 files
457 added 14 changesets with 14 changes to 3 files
457 updating to branch stable
458 updating to branch stable
458 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
459 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
459 $ rm -r ua
460 $ rm -r ua
@@ -1,129 +1,131 b''
1 # reproduce issue2264, issue2516
1 # reproduce issue2264, issue2516
2
2
3 create test repo
3 create test repo
4 $ cat <<EOF >> $HGRCPATH
4 $ cat <<EOF >> $HGRCPATH
5 > [extensions]
5 > [extensions]
6 > transplant =
6 > transplant =
7 > graphlog =
7 > graphlog =
8 > EOF
8 > EOF
9 $ hg init repo
9 $ hg init repo
10 $ cd repo
10 $ cd repo
11 $ template="{rev} {desc|firstline} [{branch}]\n"
11 $ template="{rev} {desc|firstline} [{branch}]\n"
12
12
13 # we need to start out with two changesets on the default branch
13 # we need to start out with two changesets on the default branch
14 # in order to avoid the cute little optimization where transplant
14 # in order to avoid the cute little optimization where transplant
15 # pulls rather than transplants
15 # pulls rather than transplants
16 add initial changesets
16 add initial changesets
17 $ echo feature1 > file1
17 $ echo feature1 > file1
18 $ hg ci -Am"feature 1"
18 $ hg ci -Am"feature 1"
19 adding file1
19 adding file1
20 $ echo feature2 >> file2
20 $ echo feature2 >> file2
21 $ hg ci -Am"feature 2"
21 $ hg ci -Am"feature 2"
22 adding file2
22 adding file2
23
23
24 # The changes to 'bugfix' are enough to show the bug: in fact, with only
24 # The changes to 'bugfix' are enough to show the bug: in fact, with only
25 # those changes, it's a very noisy crash ("RuntimeError: nothing
25 # those changes, it's a very noisy crash ("RuntimeError: nothing
26 # committed after transplant"). But if we modify a second file in the
26 # committed after transplant"). But if we modify a second file in the
27 # transplanted changesets, the bug is much more subtle: transplant
27 # transplanted changesets, the bug is much more subtle: transplant
28 # silently drops the second change to 'bugfix' on the floor, and we only
28 # silently drops the second change to 'bugfix' on the floor, and we only
29 # see it when we run 'hg status' after transplanting. Subtle data loss
29 # see it when we run 'hg status' after transplanting. Subtle data loss
30 # bugs are worse than crashes, so reproduce the subtle case here.
30 # bugs are worse than crashes, so reproduce the subtle case here.
31 commit bug fixes on bug fix branch
31 commit bug fixes on bug fix branch
32 $ hg branch fixes
32 $ hg branch fixes
33 marked working directory as branch fixes
33 marked working directory as branch fixes
34 (branches are permanent and global, did you want a bookmark?)
34 $ echo fix1 > bugfix
35 $ echo fix1 > bugfix
35 $ echo fix1 >> file1
36 $ echo fix1 >> file1
36 $ hg ci -Am"fix 1"
37 $ hg ci -Am"fix 1"
37 adding bugfix
38 adding bugfix
38 $ echo fix2 > bugfix
39 $ echo fix2 > bugfix
39 $ echo fix2 >> file1
40 $ echo fix2 >> file1
40 $ hg ci -Am"fix 2"
41 $ hg ci -Am"fix 2"
41 $ hg glog --template="$template"
42 $ hg glog --template="$template"
42 @ 3 fix 2 [fixes]
43 @ 3 fix 2 [fixes]
43 |
44 |
44 o 2 fix 1 [fixes]
45 o 2 fix 1 [fixes]
45 |
46 |
46 o 1 feature 2 [default]
47 o 1 feature 2 [default]
47 |
48 |
48 o 0 feature 1 [default]
49 o 0 feature 1 [default]
49
50
50 transplant bug fixes onto release branch
51 transplant bug fixes onto release branch
51 $ hg update 0
52 $ hg update 0
52 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
53 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
53 $ hg branch release
54 $ hg branch release
54 marked working directory as branch release
55 marked working directory as branch release
56 (branches are permanent and global, did you want a bookmark?)
55 $ hg transplant 2 3
57 $ hg transplant 2 3
56 applying [0-9a-f]{12} (re)
58 applying [0-9a-f]{12} (re)
57 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
59 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
58 applying [0-9a-f]{12} (re)
60 applying [0-9a-f]{12} (re)
59 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
61 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
60 $ hg glog --template="$template"
62 $ hg glog --template="$template"
61 @ 5 fix 2 [release]
63 @ 5 fix 2 [release]
62 |
64 |
63 o 4 fix 1 [release]
65 o 4 fix 1 [release]
64 |
66 |
65 | o 3 fix 2 [fixes]
67 | o 3 fix 2 [fixes]
66 | |
68 | |
67 | o 2 fix 1 [fixes]
69 | o 2 fix 1 [fixes]
68 | |
70 | |
69 | o 1 feature 2 [default]
71 | o 1 feature 2 [default]
70 |/
72 |/
71 o 0 feature 1 [default]
73 o 0 feature 1 [default]
72
74
73 $ hg status
75 $ hg status
74 $ hg status --rev 0:4
76 $ hg status --rev 0:4
75 M file1
77 M file1
76 A bugfix
78 A bugfix
77 $ hg status --rev 4:5
79 $ hg status --rev 4:5
78 M bugfix
80 M bugfix
79 M file1
81 M file1
80
82
81 now test that we fixed the bug for all scripts/extensions
83 now test that we fixed the bug for all scripts/extensions
82 $ cat > $TESTTMP/committwice.py <<__EOF__
84 $ cat > $TESTTMP/committwice.py <<__EOF__
83 > from mercurial import ui, hg, match, node
85 > from mercurial import ui, hg, match, node
84 > from time import sleep
86 > from time import sleep
85 >
87 >
86 > def replacebyte(fn, b):
88 > def replacebyte(fn, b):
87 > f = open(fn, "rb+")
89 > f = open(fn, "rb+")
88 > f.seek(0, 0)
90 > f.seek(0, 0)
89 > f.write(b)
91 > f.write(b)
90 > f.close()
92 > f.close()
91 >
93 >
92 > def printfiles(repo, rev):
94 > def printfiles(repo, rev):
93 > print "revision %s files: %s" % (rev, repo[rev].files())
95 > print "revision %s files: %s" % (rev, repo[rev].files())
94 >
96 >
95 > repo = hg.repository(ui.ui(), '.')
97 > repo = hg.repository(ui.ui(), '.')
96 > assert len(repo) == 6, \
98 > assert len(repo) == 6, \
97 > "initial: len(repo): %d, expected: 6" % len(repo)
99 > "initial: len(repo): %d, expected: 6" % len(repo)
98 >
100 >
99 > replacebyte("bugfix", "u")
101 > replacebyte("bugfix", "u")
100 > sleep(2)
102 > sleep(2)
101 > try:
103 > try:
102 > print "PRE: len(repo): %d" % len(repo)
104 > print "PRE: len(repo): %d" % len(repo)
103 > wlock = repo.wlock()
105 > wlock = repo.wlock()
104 > lock = repo.lock()
106 > lock = repo.lock()
105 > replacebyte("file1", "x")
107 > replacebyte("file1", "x")
106 > repo.commit(text="x", user="test", date=(0, 0))
108 > repo.commit(text="x", user="test", date=(0, 0))
107 > replacebyte("file1", "y")
109 > replacebyte("file1", "y")
108 > repo.commit(text="y", user="test", date=(0, 0))
110 > repo.commit(text="y", user="test", date=(0, 0))
109 > print "POST: len(repo): %d" % len(repo)
111 > print "POST: len(repo): %d" % len(repo)
110 > finally:
112 > finally:
111 > lock.release()
113 > lock.release()
112 > wlock.release()
114 > wlock.release()
113 > printfiles(repo, 6)
115 > printfiles(repo, 6)
114 > printfiles(repo, 7)
116 > printfiles(repo, 7)
115 > __EOF__
117 > __EOF__
116 $ $PYTHON $TESTTMP/committwice.py
118 $ $PYTHON $TESTTMP/committwice.py
117 PRE: len(repo): 6
119 PRE: len(repo): 6
118 POST: len(repo): 8
120 POST: len(repo): 8
119 revision 6 files: ['bugfix', 'file1']
121 revision 6 files: ['bugfix', 'file1']
120 revision 7 files: ['file1']
122 revision 7 files: ['file1']
121
123
122 Do a size-preserving modification outside of that process
124 Do a size-preserving modification outside of that process
123 $ echo abcd > bugfix
125 $ echo abcd > bugfix
124 $ hg status
126 $ hg status
125 M bugfix
127 M bugfix
126 $ hg log --template "{rev} {desc} {files}\n" -r5:
128 $ hg log --template "{rev} {desc} {files}\n" -r5:
127 5 fix 2 bugfix file1
129 5 fix 2 bugfix file1
128 6 x bugfix file1
130 6 x bugfix file1
129 7 y file1
131 7 y file1
@@ -1,84 +1,88 b''
1
1
2 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "convert = " >> $HGRCPATH
3 $ echo "convert = " >> $HGRCPATH
4 $ echo "[convert]" >> $HGRCPATH
4 $ echo "[convert]" >> $HGRCPATH
5 $ echo "hg.tagsbranch=0" >> $HGRCPATH
5 $ echo "hg.tagsbranch=0" >> $HGRCPATH
6 $ hg init source
6 $ hg init source
7 $ cd source
7 $ cd source
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -qAm adda
9 $ hg ci -qAm adda
10
10
11 Add a merge with one parent in the same branch
11 Add a merge with one parent in the same branch
12
12
13 $ echo a >> a
13 $ echo a >> a
14 $ hg ci -qAm changea
14 $ hg ci -qAm changea
15 $ hg up -qC 0
15 $ hg up -qC 0
16 $ hg branch branch0
16 $ hg branch branch0
17 marked working directory as branch branch0
17 marked working directory as branch branch0
18 (branches are permanent and global, did you want a bookmark?)
18 $ echo b > b
19 $ echo b > b
19 $ hg ci -qAm addb
20 $ hg ci -qAm addb
20 $ hg up -qC
21 $ hg up -qC
21 $ hg merge default
22 $ hg merge default
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 (branch merge, don't forget to commit)
24 (branch merge, don't forget to commit)
24 $ hg ci -qm mergeab
25 $ hg ci -qm mergeab
25 $ hg tag -ql mergeab
26 $ hg tag -ql mergeab
26 $ cd ..
27 $ cd ..
27
28
28 Miss perl... sometimes
29 Miss perl... sometimes
29
30
30 $ cat > filter.py <<EOF
31 $ cat > filter.py <<EOF
31 > import sys, re
32 > import sys, re
32 >
33 >
33 > r = re.compile(r'^(?:\d+|pulling from)')
34 > r = re.compile(r'^(?:\d+|pulling from)')
34 > sys.stdout.writelines([l for l in sys.stdin if r.search(l)])
35 > sys.stdout.writelines([l for l in sys.stdin if r.search(l)])
35 > EOF
36 > EOF
36
37
37 convert
38 convert
38
39
39 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
40 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
40 > python filter.py
41 > python filter.py
41 3 adda
42 3 adda
42 2 changea
43 2 changea
43 1 addb
44 1 addb
44 pulling from default into branch0
45 pulling from default into branch0
45 1 changesets found
46 1 changesets found
46 0 mergeab
47 0 mergeab
47 pulling from default into branch0
48 pulling from default into branch0
48 1 changesets found
49 1 changesets found
49
50
50 Add a merge with both parents and child in different branches
51 Add a merge with both parents and child in different branches
51
52
52 $ cd source
53 $ cd source
53 $ hg branch branch1
54 $ hg branch branch1
54 marked working directory as branch branch1
55 marked working directory as branch branch1
56 (branches are permanent and global, did you want a bookmark?)
55 $ echo a > file1
57 $ echo a > file1
56 $ hg ci -qAm c1
58 $ hg ci -qAm c1
57 $ hg up -qC mergeab
59 $ hg up -qC mergeab
58 $ hg branch branch2
60 $ hg branch branch2
59 marked working directory as branch branch2
61 marked working directory as branch branch2
62 (branches are permanent and global, did you want a bookmark?)
60 $ echo a > file2
63 $ echo a > file2
61 $ hg ci -qAm c2
64 $ hg ci -qAm c2
62 $ hg merge branch1
65 $ hg merge branch1
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 (branch merge, don't forget to commit)
67 (branch merge, don't forget to commit)
65 $ hg branch branch3
68 $ hg branch branch3
66 marked working directory as branch branch3
69 marked working directory as branch branch3
70 (branches are permanent and global, did you want a bookmark?)
67 $ hg ci -qAm c3
71 $ hg ci -qAm c3
68 $ cd ..
72 $ cd ..
69
73
70 incremental conversion
74 incremental conversion
71
75
72 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
76 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
73 > python filter.py
77 > python filter.py
74 2 c1
78 2 c1
75 pulling from branch0 into branch1
79 pulling from branch0 into branch1
76 4 changesets found
80 4 changesets found
77 1 c2
81 1 c2
78 pulling from branch0 into branch2
82 pulling from branch0 into branch2
79 4 changesets found
83 4 changesets found
80 0 c3
84 0 c3
81 pulling from branch2 into branch3
85 pulling from branch2 into branch3
82 5 changesets found
86 5 changesets found
83 pulling from branch1 into branch3
87 pulling from branch1 into branch3
84 1 changesets found
88 1 changesets found
@@ -1,117 +1,119 b''
1
1
2 $ cat >> $HGRCPATH <<EOF
2 $ cat >> $HGRCPATH <<EOF
3 > [extensions]
3 > [extensions]
4 > convert=
4 > convert=
5 > graphlog=
5 > graphlog=
6 > EOF
6 > EOF
7 $ hg init t
7 $ hg init t
8 $ cd t
8 $ cd t
9 $ echo a >> a
9 $ echo a >> a
10 $ hg ci -Am a0 -d '1 0'
10 $ hg ci -Am a0 -d '1 0'
11 adding a
11 adding a
12 $ hg branch brancha
12 $ hg branch brancha
13 marked working directory as branch brancha
13 marked working directory as branch brancha
14 (branches are permanent and global, did you want a bookmark?)
14 $ echo a >> a
15 $ echo a >> a
15 $ hg ci -m a1 -d '2 0'
16 $ hg ci -m a1 -d '2 0'
16 $ echo a >> a
17 $ echo a >> a
17 $ hg ci -m a2 -d '3 0'
18 $ hg ci -m a2 -d '3 0'
18 $ echo a >> a
19 $ echo a >> a
19 $ hg ci -m a3 -d '4 0'
20 $ hg ci -m a3 -d '4 0'
20 $ hg up -C 0
21 $ hg up -C 0
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 $ hg branch branchb
23 $ hg branch branchb
23 marked working directory as branch branchb
24 marked working directory as branch branchb
25 (branches are permanent and global, did you want a bookmark?)
24 $ echo b >> b
26 $ echo b >> b
25 $ hg ci -Am b0 -d '6 0'
27 $ hg ci -Am b0 -d '6 0'
26 adding b
28 adding b
27 $ hg up -C brancha
29 $ hg up -C brancha
28 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
30 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
29 $ echo a >> a
31 $ echo a >> a
30 $ hg ci -m a4 -d '5 0'
32 $ hg ci -m a4 -d '5 0'
31 $ echo a >> a
33 $ echo a >> a
32 $ hg ci -m a5 -d '7 0'
34 $ hg ci -m a5 -d '7 0'
33 $ echo a >> a
35 $ echo a >> a
34 $ hg ci -m a6 -d '8 0'
36 $ hg ci -m a6 -d '8 0'
35 $ hg up -C branchb
37 $ hg up -C branchb
36 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 $ echo b >> b
39 $ echo b >> b
38 $ hg ci -m b1 -d '9 0'
40 $ hg ci -m b1 -d '9 0'
39 $ cd ..
41 $ cd ..
40
42
41 convert with datesort
43 convert with datesort
42
44
43 $ hg convert --datesort t t-datesort
45 $ hg convert --datesort t t-datesort
44 initializing destination t-datesort repository
46 initializing destination t-datesort repository
45 scanning source...
47 scanning source...
46 sorting...
48 sorting...
47 converting...
49 converting...
48 8 a0
50 8 a0
49 7 a1
51 7 a1
50 6 a2
52 6 a2
51 5 a3
53 5 a3
52 4 a4
54 4 a4
53 3 b0
55 3 b0
54 2 a5
56 2 a5
55 1 a6
57 1 a6
56 0 b1
58 0 b1
57
59
58 graph converted repo
60 graph converted repo
59
61
60 $ hg -R t-datesort glog --template '{rev} "{desc}"\n'
62 $ hg -R t-datesort glog --template '{rev} "{desc}"\n'
61 o 8 "b1"
63 o 8 "b1"
62 |
64 |
63 | o 7 "a6"
65 | o 7 "a6"
64 | |
66 | |
65 | o 6 "a5"
67 | o 6 "a5"
66 | |
68 | |
67 o | 5 "b0"
69 o | 5 "b0"
68 | |
70 | |
69 | o 4 "a4"
71 | o 4 "a4"
70 | |
72 | |
71 | o 3 "a3"
73 | o 3 "a3"
72 | |
74 | |
73 | o 2 "a2"
75 | o 2 "a2"
74 | |
76 | |
75 | o 1 "a1"
77 | o 1 "a1"
76 |/
78 |/
77 o 0 "a0"
79 o 0 "a0"
78
80
79
81
80 convert with datesort (default mode)
82 convert with datesort (default mode)
81
83
82 $ hg convert t t-sourcesort
84 $ hg convert t t-sourcesort
83 initializing destination t-sourcesort repository
85 initializing destination t-sourcesort repository
84 scanning source...
86 scanning source...
85 sorting...
87 sorting...
86 converting...
88 converting...
87 8 a0
89 8 a0
88 7 a1
90 7 a1
89 6 a2
91 6 a2
90 5 a3
92 5 a3
91 4 b0
93 4 b0
92 3 a4
94 3 a4
93 2 a5
95 2 a5
94 1 a6
96 1 a6
95 0 b1
97 0 b1
96
98
97 graph converted repo
99 graph converted repo
98
100
99 $ hg -R t-sourcesort glog --template '{rev} "{desc}"\n'
101 $ hg -R t-sourcesort glog --template '{rev} "{desc}"\n'
100 o 8 "b1"
102 o 8 "b1"
101 |
103 |
102 | o 7 "a6"
104 | o 7 "a6"
103 | |
105 | |
104 | o 6 "a5"
106 | o 6 "a5"
105 | |
107 | |
106 | o 5 "a4"
108 | o 5 "a4"
107 | |
109 | |
108 o | 4 "b0"
110 o | 4 "b0"
109 | |
111 | |
110 | o 3 "a3"
112 | o 3 "a3"
111 | |
113 | |
112 | o 2 "a2"
114 | o 2 "a2"
113 | |
115 | |
114 | o 1 "a1"
116 | o 1 "a1"
115 |/
117 |/
116 o 0 "a0"
118 o 0 "a0"
117
119
@@ -1,374 +1,377 b''
1
1
2 $ HGMERGE=true; export HGMERGE
2 $ HGMERGE=true; export HGMERGE
3 $ echo '[extensions]' >> $HGRCPATH
3 $ echo '[extensions]' >> $HGRCPATH
4 $ echo 'graphlog =' >> $HGRCPATH
4 $ echo 'graphlog =' >> $HGRCPATH
5 $ echo 'convert =' >> $HGRCPATH
5 $ echo 'convert =' >> $HGRCPATH
6 $ glog()
6 $ glog()
7 > {
7 > {
8 > hg glog --template '{rev} "{desc}" files: {files}\n' "$@"
8 > hg glog --template '{rev} "{desc}" files: {files}\n' "$@"
9 > }
9 > }
10 $ hg init source
10 $ hg init source
11 $ cd source
11 $ cd source
12 $ echo foo > foo
12 $ echo foo > foo
13 $ echo baz > baz
13 $ echo baz > baz
14 $ mkdir -p dir/subdir
14 $ mkdir -p dir/subdir
15 $ echo dir/file >> dir/file
15 $ echo dir/file >> dir/file
16 $ echo dir/file2 >> dir/file2
16 $ echo dir/file2 >> dir/file2
17 $ echo dir/file3 >> dir/file3 # to be corrupted in rev 0
17 $ echo dir/file3 >> dir/file3 # to be corrupted in rev 0
18 $ echo dir/subdir/file3 >> dir/subdir/file3
18 $ echo dir/subdir/file3 >> dir/subdir/file3
19 $ echo dir/subdir/file4 >> dir/subdir/file4
19 $ echo dir/subdir/file4 >> dir/subdir/file4
20 $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
20 $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
21 $ echo bar > bar
21 $ echo bar > bar
22 $ echo quux > quux
22 $ echo quux > quux
23 $ echo dir/file4 >> dir/file4 # to be corrupted in rev 1
23 $ echo dir/file4 >> dir/file4 # to be corrupted in rev 1
24 $ hg copy foo copied
24 $ hg copy foo copied
25 $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
25 $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
26 $ echo >> foo
26 $ echo >> foo
27 $ hg ci -d '2 0' -m '2: change foo'
27 $ hg ci -d '2 0' -m '2: change foo'
28 $ hg up -qC 1
28 $ hg up -qC 1
29 $ echo >> bar
29 $ echo >> bar
30 $ echo >> quux
30 $ echo >> quux
31 $ hg ci -d '3 0' -m '3: change bar quux'
31 $ hg ci -d '3 0' -m '3: change bar quux'
32 created new head
32 created new head
33 $ hg up -qC 2
33 $ hg up -qC 2
34 $ hg merge -qr 3
34 $ hg merge -qr 3
35 $ echo >> bar
35 $ echo >> bar
36 $ echo >> baz
36 $ echo >> baz
37 $ hg ci -d '4 0' -m '4: first merge; change bar baz'
37 $ hg ci -d '4 0' -m '4: first merge; change bar baz'
38 $ echo >> bar
38 $ echo >> bar
39 $ echo 1 >> baz
39 $ echo 1 >> baz
40 $ echo >> quux
40 $ echo >> quux
41 $ hg ci -d '5 0' -m '5: change bar baz quux'
41 $ hg ci -d '5 0' -m '5: change bar baz quux'
42 $ hg up -qC 4
42 $ hg up -qC 4
43 $ echo >> foo
43 $ echo >> foo
44 $ echo 2 >> baz
44 $ echo 2 >> baz
45 $ hg ci -d '6 0' -m '6: change foo baz'
45 $ hg ci -d '6 0' -m '6: change foo baz'
46 created new head
46 created new head
47 $ hg up -qC 5
47 $ hg up -qC 5
48 $ hg merge -qr 6
48 $ hg merge -qr 6
49 $ echo >> bar
49 $ echo >> bar
50 $ hg ci -d '7 0' -m '7: second merge; change bar'
50 $ hg ci -d '7 0' -m '7: second merge; change bar'
51 $ echo >> foo
51 $ echo >> foo
52 $ hg ci -m '8: change foo'
52 $ hg ci -m '8: change foo'
53 $ glog
53 $ glog
54 @ 8 "8: change foo" files: foo
54 @ 8 "8: change foo" files: foo
55 |
55 |
56 o 7 "7: second merge; change bar" files: bar baz
56 o 7 "7: second merge; change bar" files: bar baz
57 |\
57 |\
58 | o 6 "6: change foo baz" files: baz foo
58 | o 6 "6: change foo baz" files: baz foo
59 | |
59 | |
60 o | 5 "5: change bar baz quux" files: bar baz quux
60 o | 5 "5: change bar baz quux" files: bar baz quux
61 |/
61 |/
62 o 4 "4: first merge; change bar baz" files: bar baz
62 o 4 "4: first merge; change bar baz" files: bar baz
63 |\
63 |\
64 | o 3 "3: change bar quux" files: bar quux
64 | o 3 "3: change bar quux" files: bar quux
65 | |
65 | |
66 o | 2 "2: change foo" files: foo
66 o | 2 "2: change foo" files: foo
67 |/
67 |/
68 o 1 "1: add bar quux; copy foo to copied" files: bar copied dir/file4 quux
68 o 1 "1: add bar quux; copy foo to copied" files: bar copied dir/file4 quux
69 |
69 |
70 o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/file3 dir/subdir/file3 dir/subdir/file4 foo
70 o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/file3 dir/subdir/file3 dir/subdir/file4 foo
71
71
72
72
73 final file versions in this repo:
73 final file versions in this repo:
74
74
75 $ hg manifest --debug
75 $ hg manifest --debug
76 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
76 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
77 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
77 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
78 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
78 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
79 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file
79 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file
80 75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2
80 75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2
81 e96dce0bc6a217656a3a410e5e6bec2c4f42bf7c 644 dir/file3
81 e96dce0bc6a217656a3a410e5e6bec2c4f42bf7c 644 dir/file3
82 6edd55f559cdce67132b12ca09e09cee08b60442 644 dir/file4
82 6edd55f559cdce67132b12ca09e09cee08b60442 644 dir/file4
83 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3
83 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3
84 57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4
84 57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4
85 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
85 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
86 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
86 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
87 $ hg debugrename copied
87 $ hg debugrename copied
88 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
88 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
89
89
90 $ cd ..
90 $ cd ..
91 $ splitrepo()
91 $ splitrepo()
92 > {
92 > {
93 > msg="$1"
93 > msg="$1"
94 > files="$2"
94 > files="$2"
95 > opts=$3
95 > opts=$3
96 > echo "% $files: $msg"
96 > echo "% $files: $msg"
97 > prefix=`echo "$files" | sed -e 's/ /-/g'`
97 > prefix=`echo "$files" | sed -e 's/ /-/g'`
98 > fmap="$prefix.fmap"
98 > fmap="$prefix.fmap"
99 > repo="$prefix.repo"
99 > repo="$prefix.repo"
100 > for i in $files; do
100 > for i in $files; do
101 > echo "include $i" >> "$fmap"
101 > echo "include $i" >> "$fmap"
102 > done
102 > done
103 > hg -q convert $opts --filemap "$fmap" --datesort source "$repo"
103 > hg -q convert $opts --filemap "$fmap" --datesort source "$repo"
104 > hg up -q -R "$repo"
104 > hg up -q -R "$repo"
105 > glog -R "$repo"
105 > glog -R "$repo"
106 > hg -R "$repo" manifest --debug
106 > hg -R "$repo" manifest --debug
107 > }
107 > }
108 $ splitrepo 'skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd' foo
108 $ splitrepo 'skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd' foo
109 % foo: skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd
109 % foo: skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd
110 @ 3 "8: change foo" files: foo
110 @ 3 "8: change foo" files: foo
111 |
111 |
112 o 2 "6: change foo baz" files: foo
112 o 2 "6: change foo baz" files: foo
113 |
113 |
114 o 1 "2: change foo" files: foo
114 o 1 "2: change foo" files: foo
115 |
115 |
116 o 0 "0: add foo baz dir/" files: foo
116 o 0 "0: add foo baz dir/" files: foo
117
117
118 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
118 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
119 $ splitrepo 'merges are not merges anymore' bar
119 $ splitrepo 'merges are not merges anymore' bar
120 % bar: merges are not merges anymore
120 % bar: merges are not merges anymore
121 @ 4 "7: second merge; change bar" files: bar
121 @ 4 "7: second merge; change bar" files: bar
122 |
122 |
123 o 3 "5: change bar baz quux" files: bar
123 o 3 "5: change bar baz quux" files: bar
124 |
124 |
125 o 2 "4: first merge; change bar baz" files: bar
125 o 2 "4: first merge; change bar baz" files: bar
126 |
126 |
127 o 1 "3: change bar quux" files: bar
127 o 1 "3: change bar quux" files: bar
128 |
128 |
129 o 0 "1: add bar quux; copy foo to copied" files: bar
129 o 0 "1: add bar quux; copy foo to copied" files: bar
130
130
131 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
131 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
132 $ splitrepo '1st merge is not a merge anymore; 2nd still is' baz
132 $ splitrepo '1st merge is not a merge anymore; 2nd still is' baz
133 % baz: 1st merge is not a merge anymore; 2nd still is
133 % baz: 1st merge is not a merge anymore; 2nd still is
134 @ 4 "7: second merge; change bar" files: baz
134 @ 4 "7: second merge; change bar" files: baz
135 |\
135 |\
136 | o 3 "6: change foo baz" files: baz
136 | o 3 "6: change foo baz" files: baz
137 | |
137 | |
138 o | 2 "5: change bar baz quux" files: baz
138 o | 2 "5: change bar baz quux" files: baz
139 |/
139 |/
140 o 1 "4: first merge; change bar baz" files: baz
140 o 1 "4: first merge; change bar baz" files: baz
141 |
141 |
142 o 0 "0: add foo baz dir/" files: baz
142 o 0 "0: add foo baz dir/" files: baz
143
143
144 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
144 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
145 $ splitrepo 'we add additional merges when they are interesting' 'foo quux'
145 $ splitrepo 'we add additional merges when they are interesting' 'foo quux'
146 % foo quux: we add additional merges when they are interesting
146 % foo quux: we add additional merges when they are interesting
147 @ 8 "8: change foo" files: foo
147 @ 8 "8: change foo" files: foo
148 |
148 |
149 o 7 "7: second merge; change bar" files:
149 o 7 "7: second merge; change bar" files:
150 |\
150 |\
151 | o 6 "6: change foo baz" files: foo
151 | o 6 "6: change foo baz" files: foo
152 | |
152 | |
153 o | 5 "5: change bar baz quux" files: quux
153 o | 5 "5: change bar baz quux" files: quux
154 |/
154 |/
155 o 4 "4: first merge; change bar baz" files:
155 o 4 "4: first merge; change bar baz" files:
156 |\
156 |\
157 | o 3 "3: change bar quux" files: quux
157 | o 3 "3: change bar quux" files: quux
158 | |
158 | |
159 o | 2 "2: change foo" files: foo
159 o | 2 "2: change foo" files: foo
160 |/
160 |/
161 o 1 "1: add bar quux; copy foo to copied" files: quux
161 o 1 "1: add bar quux; copy foo to copied" files: quux
162 |
162 |
163 o 0 "0: add foo baz dir/" files: foo
163 o 0 "0: add foo baz dir/" files: foo
164
164
165 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
165 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
166 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
166 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
167 $ splitrepo 'partial conversion' 'bar quux' '-r 3'
167 $ splitrepo 'partial conversion' 'bar quux' '-r 3'
168 % bar quux: partial conversion
168 % bar quux: partial conversion
169 @ 1 "3: change bar quux" files: bar quux
169 @ 1 "3: change bar quux" files: bar quux
170 |
170 |
171 o 0 "1: add bar quux; copy foo to copied" files: bar quux
171 o 0 "1: add bar quux; copy foo to copied" files: bar quux
172
172
173 b79105bedc55102f394e90a789c9c380117c1b4a 644 bar
173 b79105bedc55102f394e90a789c9c380117c1b4a 644 bar
174 db0421cc6b685a458c8d86c7d5c004f94429ea23 644 quux
174 db0421cc6b685a458c8d86c7d5c004f94429ea23 644 quux
175 $ splitrepo 'complete the partial conversion' 'bar quux'
175 $ splitrepo 'complete the partial conversion' 'bar quux'
176 % bar quux: complete the partial conversion
176 % bar quux: complete the partial conversion
177 @ 4 "7: second merge; change bar" files: bar
177 @ 4 "7: second merge; change bar" files: bar
178 |
178 |
179 o 3 "5: change bar baz quux" files: bar quux
179 o 3 "5: change bar baz quux" files: bar quux
180 |
180 |
181 o 2 "4: first merge; change bar baz" files: bar
181 o 2 "4: first merge; change bar baz" files: bar
182 |
182 |
183 o 1 "3: change bar quux" files: bar quux
183 o 1 "3: change bar quux" files: bar quux
184 |
184 |
185 o 0 "1: add bar quux; copy foo to copied" files: bar quux
185 o 0 "1: add bar quux; copy foo to copied" files: bar quux
186
186
187 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
187 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
188 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
188 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
189 $ rm -r foo.repo
189 $ rm -r foo.repo
190 $ splitrepo 'partial conversion' 'foo' '-r 3'
190 $ splitrepo 'partial conversion' 'foo' '-r 3'
191 % foo: partial conversion
191 % foo: partial conversion
192 @ 0 "0: add foo baz dir/" files: foo
192 @ 0 "0: add foo baz dir/" files: foo
193
193
194 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
194 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
195 $ splitrepo 'complete the partial conversion' 'foo'
195 $ splitrepo 'complete the partial conversion' 'foo'
196 % foo: complete the partial conversion
196 % foo: complete the partial conversion
197 @ 3 "8: change foo" files: foo
197 @ 3 "8: change foo" files: foo
198 |
198 |
199 o 2 "6: change foo baz" files: foo
199 o 2 "6: change foo baz" files: foo
200 |
200 |
201 o 1 "2: change foo" files: foo
201 o 1 "2: change foo" files: foo
202 |
202 |
203 o 0 "0: add foo baz dir/" files: foo
203 o 0 "0: add foo baz dir/" files: foo
204
204
205 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
205 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
206 $ splitrepo 'copied file; source not included in new repo' copied
206 $ splitrepo 'copied file; source not included in new repo' copied
207 % copied: copied file; source not included in new repo
207 % copied: copied file; source not included in new repo
208 @ 0 "1: add bar quux; copy foo to copied" files: copied
208 @ 0 "1: add bar quux; copy foo to copied" files: copied
209
209
210 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 copied
210 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 copied
211 $ hg --cwd copied.repo debugrename copied
211 $ hg --cwd copied.repo debugrename copied
212 copied not renamed
212 copied not renamed
213 $ splitrepo 'copied file; source included in new repo' 'foo copied'
213 $ splitrepo 'copied file; source included in new repo' 'foo copied'
214 % foo copied: copied file; source included in new repo
214 % foo copied: copied file; source included in new repo
215 @ 4 "8: change foo" files: foo
215 @ 4 "8: change foo" files: foo
216 |
216 |
217 o 3 "6: change foo baz" files: foo
217 o 3 "6: change foo baz" files: foo
218 |
218 |
219 o 2 "2: change foo" files: foo
219 o 2 "2: change foo" files: foo
220 |
220 |
221 o 1 "1: add bar quux; copy foo to copied" files: copied
221 o 1 "1: add bar quux; copy foo to copied" files: copied
222 |
222 |
223 o 0 "0: add foo baz dir/" files: foo
223 o 0 "0: add foo baz dir/" files: foo
224
224
225 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
225 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
226 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
226 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
227 $ hg --cwd foo-copied.repo debugrename copied
227 $ hg --cwd foo-copied.repo debugrename copied
228 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
228 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
229 $ cat > renames.fmap <<EOF
229 $ cat > renames.fmap <<EOF
230 > include dir
230 > include dir
231 > exclude dir/file2
231 > exclude dir/file2
232 > rename dir dir2
232 > rename dir dir2
233 > include foo
233 > include foo
234 > include copied
234 > include copied
235 > rename foo foo2
235 > rename foo foo2
236 > rename copied copied2
236 > rename copied copied2
237 > exclude dir/subdir
237 > exclude dir/subdir
238 > include dir/subdir/file3
238 > include dir/subdir/file3
239 > EOF
239 > EOF
240 $ rm source/.hg/store/data/dir/file3.i
240 $ rm source/.hg/store/data/dir/file3.i
241 $ rm source/.hg/store/data/dir/file4.i
241 $ rm source/.hg/store/data/dir/file4.i
242 $ hg -q convert --filemap renames.fmap --datesort source dummydest
242 $ hg -q convert --filemap renames.fmap --datesort source dummydest
243 abort: data/dir/file3.i@e96dce0bc6a2: no match found!
243 abort: data/dir/file3.i@e96dce0bc6a2: no match found!
244 [255]
244 [255]
245 $ hg -q convert --filemap renames.fmap --datesort --config convert.hg.ignoreerrors=1 source renames.repo
245 $ hg -q convert --filemap renames.fmap --datesort --config convert.hg.ignoreerrors=1 source renames.repo
246 ignoring: data/dir/file3.i@e96dce0bc6a2: no match found
246 ignoring: data/dir/file3.i@e96dce0bc6a2: no match found
247 ignoring: data/dir/file4.i@6edd55f559cd: no match found
247 ignoring: data/dir/file4.i@6edd55f559cd: no match found
248 $ hg up -q -R renames.repo
248 $ hg up -q -R renames.repo
249 $ glog -R renames.repo
249 $ glog -R renames.repo
250 @ 4 "8: change foo" files: foo2
250 @ 4 "8: change foo" files: foo2
251 |
251 |
252 o 3 "6: change foo baz" files: foo2
252 o 3 "6: change foo baz" files: foo2
253 |
253 |
254 o 2 "2: change foo" files: foo2
254 o 2 "2: change foo" files: foo2
255 |
255 |
256 o 1 "1: add bar quux; copy foo to copied" files: copied2
256 o 1 "1: add bar quux; copy foo to copied" files: copied2
257 |
257 |
258 o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
258 o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
259
259
260 $ hg -R renames.repo manifest --debug
260 $ hg -R renames.repo manifest --debug
261 d43feacba7a4f1f2080dde4a4b985bd8a0236d46 644 copied2
261 d43feacba7a4f1f2080dde4a4b985bd8a0236d46 644 copied2
262 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
262 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
263 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
263 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
264 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
264 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
265 $ hg --cwd renames.repo debugrename copied2
265 $ hg --cwd renames.repo debugrename copied2
266 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
266 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
267
267
268 copied:
268 copied:
269
269
270 $ hg --cwd source cat copied
270 $ hg --cwd source cat copied
271 foo
271 foo
272
272
273 copied2:
273 copied2:
274
274
275 $ hg --cwd renames.repo cat copied2
275 $ hg --cwd renames.repo cat copied2
276 foo
276 foo
277
277
278 filemap errors
278 filemap errors
279
279
280 $ cat > errors.fmap <<EOF
280 $ cat > errors.fmap <<EOF
281 > include dir/ # beware that comments changes error line numbers!
281 > include dir/ # beware that comments changes error line numbers!
282 > exclude /dir
282 > exclude /dir
283 > rename dir//dir /dir//dir/ "out of sync"
283 > rename dir//dir /dir//dir/ "out of sync"
284 > include
284 > include
285 > EOF
285 > EOF
286 $ hg -q convert --filemap errors.fmap source errors.repo
286 $ hg -q convert --filemap errors.fmap source errors.repo
287 errors.fmap:1: superfluous / in exclude 'dir/'
287 errors.fmap:1: superfluous / in exclude 'dir/'
288 errors.fmap:3: superfluous / in include '/dir'
288 errors.fmap:3: superfluous / in include '/dir'
289 errors.fmap:3: superfluous / in rename '/dir'
289 errors.fmap:3: superfluous / in rename '/dir'
290 errors.fmap:3: superfluous / in exclude 'dir//dir'
290 errors.fmap:3: superfluous / in exclude 'dir//dir'
291 errors.fmap:4: unknown directive 'out of sync'
291 errors.fmap:4: unknown directive 'out of sync'
292 errors.fmap:5: path to exclude is missing
292 errors.fmap:5: path to exclude is missing
293 abort: errors in filemap
293 abort: errors in filemap
294 [255]
294 [255]
295
295
296 test branch closing revision pruning if branch is pruned
296 test branch closing revision pruning if branch is pruned
297
297
298 $ hg init branchpruning
298 $ hg init branchpruning
299 $ cd branchpruning
299 $ cd branchpruning
300 $ hg branch foo
300 $ hg branch foo
301 marked working directory as branch foo
301 marked working directory as branch foo
302 (branches are permanent and global, did you want a bookmark?)
302 $ echo a > a
303 $ echo a > a
303 $ hg ci -Am adda
304 $ hg ci -Am adda
304 adding a
305 adding a
305 $ hg ci --close-branch -m closefoo
306 $ hg ci --close-branch -m closefoo
306 $ hg up 0
307 $ hg up 0
307 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
308 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
308 $ hg branch empty
309 $ hg branch empty
309 marked working directory as branch empty
310 marked working directory as branch empty
311 (branches are permanent and global, did you want a bookmark?)
310 $ hg ci -m emptybranch
312 $ hg ci -m emptybranch
311 $ hg ci --close-branch -m closeempty
313 $ hg ci --close-branch -m closeempty
312 $ hg up 0
314 $ hg up 0
313 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
315 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 $ hg branch default
316 $ hg branch default
315 marked working directory as branch default
317 marked working directory as branch default
318 (branches are permanent and global, did you want a bookmark?)
316 $ echo b > b
319 $ echo b > b
317 $ hg ci -Am addb
320 $ hg ci -Am addb
318 adding b
321 adding b
319 $ hg ci --close-branch -m closedefault
322 $ hg ci --close-branch -m closedefault
320 $ cat > filemap <<EOF
323 $ cat > filemap <<EOF
321 > include b
324 > include b
322 > EOF
325 > EOF
323 $ cd ..
326 $ cd ..
324 $ hg convert branchpruning branchpruning-hg1
327 $ hg convert branchpruning branchpruning-hg1
325 initializing destination branchpruning-hg1 repository
328 initializing destination branchpruning-hg1 repository
326 scanning source...
329 scanning source...
327 sorting...
330 sorting...
328 converting...
331 converting...
329 5 adda
332 5 adda
330 4 closefoo
333 4 closefoo
331 3 emptybranch
334 3 emptybranch
332 2 closeempty
335 2 closeempty
333 1 addb
336 1 addb
334 0 closedefault
337 0 closedefault
335 $ glog -R branchpruning-hg1
338 $ glog -R branchpruning-hg1
336 o 5 "closedefault" files:
339 o 5 "closedefault" files:
337 |
340 |
338 o 4 "addb" files: b
341 o 4 "addb" files: b
339 |
342 |
340 | o 3 "closeempty" files:
343 | o 3 "closeempty" files:
341 | |
344 | |
342 | o 2 "emptybranch" files:
345 | o 2 "emptybranch" files:
343 |/
346 |/
344 | o 1 "closefoo" files:
347 | o 1 "closefoo" files:
345 |/
348 |/
346 o 0 "adda" files: a
349 o 0 "adda" files: a
347
350
348
351
349 exercise incremental conversion at the same time
352 exercise incremental conversion at the same time
350
353
351 $ hg convert -r0 --filemap branchpruning/filemap branchpruning branchpruning-hg2
354 $ hg convert -r0 --filemap branchpruning/filemap branchpruning branchpruning-hg2
352 initializing destination branchpruning-hg2 repository
355 initializing destination branchpruning-hg2 repository
353 scanning source...
356 scanning source...
354 sorting...
357 sorting...
355 converting...
358 converting...
356 0 adda
359 0 adda
357 $ hg convert -r4 --filemap branchpruning/filemap branchpruning branchpruning-hg2
360 $ hg convert -r4 --filemap branchpruning/filemap branchpruning branchpruning-hg2
358 scanning source...
361 scanning source...
359 sorting...
362 sorting...
360 converting...
363 converting...
361 0 addb
364 0 addb
362 $ hg convert --filemap branchpruning/filemap branchpruning branchpruning-hg2
365 $ hg convert --filemap branchpruning/filemap branchpruning branchpruning-hg2
363 scanning source...
366 scanning source...
364 sorting...
367 sorting...
365 converting...
368 converting...
366 3 closefoo
369 3 closefoo
367 2 emptybranch
370 2 emptybranch
368 1 closeempty
371 1 closeempty
369 0 closedefault
372 0 closedefault
370 $ glog -R branchpruning-hg2
373 $ glog -R branchpruning-hg2
371 o 1 "closedefault" files:
374 o 1 "closedefault" files:
372 |
375 |
373 o 0 "addb" files: b
376 o 0 "addb" files: b
374
377
@@ -1,140 +1,143 b''
1 Test alignment of multibyte characters
1 Test alignment of multibyte characters
2
2
3 $ HGENCODING=utf-8
3 $ HGENCODING=utf-8
4 $ export HGENCODING
4 $ export HGENCODING
5 $ hg init t
5 $ hg init t
6 $ cd t
6 $ cd t
7 $ python << EOF
7 $ python << EOF
8 > # (byte, width) = (6, 4)
8 > # (byte, width) = (6, 4)
9 > s = "\xe7\x9f\xad\xe5\x90\x8d"
9 > s = "\xe7\x9f\xad\xe5\x90\x8d"
10 > # (byte, width) = (7, 7): odd width is good for alignment test
10 > # (byte, width) = (7, 7): odd width is good for alignment test
11 > m = "MIDDLE_"
11 > m = "MIDDLE_"
12 > # (byte, width) = (18, 12)
12 > # (byte, width) = (18, 12)
13 > l = "\xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d"
13 > l = "\xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d"
14 > f = file('s', 'w'); f.write(s); f.close()
14 > f = file('s', 'w'); f.write(s); f.close()
15 > f = file('m', 'w'); f.write(m); f.close()
15 > f = file('m', 'w'); f.write(m); f.close()
16 > f = file('l', 'w'); f.write(l); f.close()
16 > f = file('l', 'w'); f.write(l); f.close()
17 > # instant extension to show list of options
17 > # instant extension to show list of options
18 > f = file('showoptlist.py', 'w'); f.write("""# encoding: utf-8
18 > f = file('showoptlist.py', 'w'); f.write("""# encoding: utf-8
19 > def showoptlist(ui, repo, *pats, **opts):
19 > def showoptlist(ui, repo, *pats, **opts):
20 > '''dummy command to show option descriptions'''
20 > '''dummy command to show option descriptions'''
21 > return 0
21 > return 0
22 > cmdtable = {
22 > cmdtable = {
23 > 'showoptlist':
23 > 'showoptlist':
24 > (showoptlist,
24 > (showoptlist,
25 > [('s', 'opt1', '', 'short width' + ' %(s)s' * 8, '%(s)s'),
25 > [('s', 'opt1', '', 'short width' + ' %(s)s' * 8, '%(s)s'),
26 > ('m', 'opt2', '', 'middle width' + ' %(m)s' * 8, '%(m)s'),
26 > ('m', 'opt2', '', 'middle width' + ' %(m)s' * 8, '%(m)s'),
27 > ('l', 'opt3', '', 'long width' + ' %(l)s' * 8, '%(l)s')
27 > ('l', 'opt3', '', 'long width' + ' %(l)s' * 8, '%(l)s')
28 > ],
28 > ],
29 > ""
29 > ""
30 > )
30 > )
31 > }
31 > }
32 > """ % globals())
32 > """ % globals())
33 > f.close()
33 > f.close()
34 > EOF
34 > EOF
35 $ S=`cat s`
35 $ S=`cat s`
36 $ M=`cat m`
36 $ M=`cat m`
37 $ L=`cat l`
37 $ L=`cat l`
38
38
39 alignment of option descriptions in help
39 alignment of option descriptions in help
40
40
41 $ cat <<EOF > .hg/hgrc
41 $ cat <<EOF > .hg/hgrc
42 > [extensions]
42 > [extensions]
43 > ja_ext = `pwd`/showoptlist.py
43 > ja_ext = `pwd`/showoptlist.py
44 > EOF
44 > EOF
45
45
46 check alignment of option descriptions in help
46 check alignment of option descriptions in help
47
47
48 $ hg help showoptlist
48 $ hg help showoptlist
49 hg showoptlist
49 hg showoptlist
50
50
51 dummy command to show option descriptions
51 dummy command to show option descriptions
52
52
53 options:
53 options:
54
54
55 -s --opt1 \xe7\x9f\xad\xe5\x90\x8d short width \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d (esc)
55 -s --opt1 \xe7\x9f\xad\xe5\x90\x8d short width \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d (esc)
56 -m --opt2 MIDDLE_ middle width MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_
56 -m --opt2 MIDDLE_ middle width MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_
57 MIDDLE_ MIDDLE_ MIDDLE_
57 MIDDLE_ MIDDLE_ MIDDLE_
58 -l --opt3 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d long width \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
58 -l --opt3 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d long width \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
59 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
59 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
60 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
60 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
61
61
62 use "hg -v help showoptlist" to show more info
62 use "hg -v help showoptlist" to show more info
63
63
64
64
65 $ rm -f s; touch s
65 $ rm -f s; touch s
66 $ rm -f m; touch m
66 $ rm -f m; touch m
67 $ rm -f l; touch l
67 $ rm -f l; touch l
68
68
69 add files
69 add files
70
70
71 $ cp s $S
71 $ cp s $S
72 $ hg add $S
72 $ hg add $S
73 $ cp m $M
73 $ cp m $M
74 $ hg add $M
74 $ hg add $M
75 $ cp l $L
75 $ cp l $L
76 $ hg add $L
76 $ hg add $L
77
77
78 commit(1)
78 commit(1)
79
79
80 $ echo 'first line(1)' >> s; cp s $S
80 $ echo 'first line(1)' >> s; cp s $S
81 $ echo 'first line(2)' >> m; cp m $M
81 $ echo 'first line(2)' >> m; cp m $M
82 $ echo 'first line(3)' >> l; cp l $L
82 $ echo 'first line(3)' >> l; cp l $L
83 $ hg commit -m 'first commit' -u $S
83 $ hg commit -m 'first commit' -u $S
84
84
85 commit(2)
85 commit(2)
86
86
87 $ echo 'second line(1)' >> s; cp s $S
87 $ echo 'second line(1)' >> s; cp s $S
88 $ echo 'second line(2)' >> m; cp m $M
88 $ echo 'second line(2)' >> m; cp m $M
89 $ echo 'second line(3)' >> l; cp l $L
89 $ echo 'second line(3)' >> l; cp l $L
90 $ hg commit -m 'second commit' -u $M
90 $ hg commit -m 'second commit' -u $M
91
91
92 commit(3)
92 commit(3)
93
93
94 $ echo 'third line(1)' >> s; cp s $S
94 $ echo 'third line(1)' >> s; cp s $S
95 $ echo 'third line(2)' >> m; cp m $M
95 $ echo 'third line(2)' >> m; cp m $M
96 $ echo 'third line(3)' >> l; cp l $L
96 $ echo 'third line(3)' >> l; cp l $L
97 $ hg commit -m 'third commit' -u $L
97 $ hg commit -m 'third commit' -u $L
98
98
99 check alignment of user names in annotate
99 check alignment of user names in annotate
100
100
101 $ hg annotate -u $M
101 $ hg annotate -u $M
102 \xe7\x9f\xad\xe5\x90\x8d: first line(2) (esc)
102 \xe7\x9f\xad\xe5\x90\x8d: first line(2) (esc)
103 MIDDLE_: second line(2)
103 MIDDLE_: second line(2)
104 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d: third line(2) (esc)
104 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d: third line(2) (esc)
105
105
106 check alignment of filenames in diffstat
106 check alignment of filenames in diffstat
107
107
108 $ hg diff -c tip --stat
108 $ hg diff -c tip --stat
109 MIDDLE_ | 1 +
109 MIDDLE_ | 1 +
110 \xe7\x9f\xad\xe5\x90\x8d | 1 + (esc)
110 \xe7\x9f\xad\xe5\x90\x8d | 1 + (esc)
111 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d | 1 + (esc)
111 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d | 1 + (esc)
112 3 files changed, 3 insertions(+), 0 deletions(-)
112 3 files changed, 3 insertions(+), 0 deletions(-)
113
113
114 add branches/tags
114 add branches/tags
115
115
116 $ hg branch $S
116 $ hg branch $S
117 marked working directory as branch \xe7\x9f\xad\xe5\x90\x8d (esc)
117 marked working directory as branch \xe7\x9f\xad\xe5\x90\x8d (esc)
118 (branches are permanent and global, did you want a bookmark?)
118 $ hg tag $S
119 $ hg tag $S
119 $ hg branch $M
120 $ hg branch $M
120 marked working directory as branch MIDDLE_
121 marked working directory as branch MIDDLE_
122 (branches are permanent and global, did you want a bookmark?)
121 $ hg tag $M
123 $ hg tag $M
122 $ hg branch $L
124 $ hg branch $L
123 marked working directory as branch \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
125 marked working directory as branch \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
126 (branches are permanent and global, did you want a bookmark?)
124 $ hg tag $L
127 $ hg tag $L
125
128
126 check alignment of branches
129 check alignment of branches
127
130
128 $ hg tags
131 $ hg tags
129 tip 5:d745ff46155b
132 tip 5:d745ff46155b
130 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
133 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
131 MIDDLE_ 3:b06c5b6def9e
134 MIDDLE_ 3:b06c5b6def9e
132 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
135 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
133
136
134 check alignment of tags
137 check alignment of tags
135
138
136 $ hg tags
139 $ hg tags
137 tip 5:d745ff46155b
140 tip 5:d745ff46155b
138 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
141 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
139 MIDDLE_ 3:b06c5b6def9e
142 MIDDLE_ 3:b06c5b6def9e
140 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
143 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
@@ -1,249 +1,250 b''
1 Test character encoding
1 Test character encoding
2
2
3 $ hg init t
3 $ hg init t
4 $ cd t
4 $ cd t
5
5
6 we need a repo with some legacy latin-1 changesets
6 we need a repo with some legacy latin-1 changesets
7
7
8 $ hg unbundle $TESTDIR/bundles/legacy-encoding.hg
8 $ hg unbundle $TESTDIR/bundles/legacy-encoding.hg
9 adding changesets
9 adding changesets
10 adding manifests
10 adding manifests
11 adding file changes
11 adding file changes
12 added 2 changesets with 2 changes to 1 files
12 added 2 changesets with 2 changes to 1 files
13 (run 'hg update' to get a working copy)
13 (run 'hg update' to get a working copy)
14 $ hg co
14 $ hg co
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ python << EOF
16 $ python << EOF
17 > f = file('latin-1', 'w'); f.write("latin-1 e' encoded: \xe9"); f.close()
17 > f = file('latin-1', 'w'); f.write("latin-1 e' encoded: \xe9"); f.close()
18 > f = file('utf-8', 'w'); f.write("utf-8 e' encoded: \xc3\xa9"); f.close()
18 > f = file('utf-8', 'w'); f.write("utf-8 e' encoded: \xc3\xa9"); f.close()
19 > f = file('latin-1-tag', 'w'); f.write("\xe9"); f.close()
19 > f = file('latin-1-tag', 'w'); f.write("\xe9"); f.close()
20 > EOF
20 > EOF
21
21
22 should fail with encoding error
22 should fail with encoding error
23
23
24 $ echo "plain old ascii" > a
24 $ echo "plain old ascii" > a
25 $ hg st
25 $ hg st
26 M a
26 M a
27 ? latin-1
27 ? latin-1
28 ? latin-1-tag
28 ? latin-1-tag
29 ? utf-8
29 ? utf-8
30 $ HGENCODING=ascii hg ci -l latin-1
30 $ HGENCODING=ascii hg ci -l latin-1
31 transaction abort!
31 transaction abort!
32 rollback completed
32 rollback completed
33 abort: decoding near ' encoded: \xe9': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)! (esc)
33 abort: decoding near ' encoded: \xe9': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)! (esc)
34 [255]
34 [255]
35
35
36 these should work
36 these should work
37
37
38 $ echo "latin-1" > a
38 $ echo "latin-1" > a
39 $ HGENCODING=latin-1 hg ci -l latin-1
39 $ HGENCODING=latin-1 hg ci -l latin-1
40 $ echo "utf-8" > a
40 $ echo "utf-8" > a
41 $ HGENCODING=utf-8 hg ci -l utf-8
41 $ HGENCODING=utf-8 hg ci -l utf-8
42 $ HGENCODING=latin-1 hg tag `cat latin-1-tag`
42 $ HGENCODING=latin-1 hg tag `cat latin-1-tag`
43 $ HGENCODING=latin-1 hg branch `cat latin-1-tag`
43 $ HGENCODING=latin-1 hg branch `cat latin-1-tag`
44 marked working directory as branch \xe9 (esc)
44 marked working directory as branch \xe9 (esc)
45 (branches are permanent and global, did you want a bookmark?)
45 $ HGENCODING=latin-1 hg ci -m 'latin1 branch'
46 $ HGENCODING=latin-1 hg ci -m 'latin1 branch'
46 $ rm .hg/branch
47 $ rm .hg/branch
47
48
48 hg log (ascii)
49 hg log (ascii)
49
50
50 $ hg --encoding ascii log
51 $ hg --encoding ascii log
51 changeset: 5:a52c0692f24a
52 changeset: 5:a52c0692f24a
52 branch: ?
53 branch: ?
53 tag: tip
54 tag: tip
54 user: test
55 user: test
55 date: Thu Jan 01 00:00:00 1970 +0000
56 date: Thu Jan 01 00:00:00 1970 +0000
56 summary: latin1 branch
57 summary: latin1 branch
57
58
58 changeset: 4:94db611b4196
59 changeset: 4:94db611b4196
59 user: test
60 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
61 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: Added tag ? for changeset ca661e7520de
62 summary: Added tag ? for changeset ca661e7520de
62
63
63 changeset: 3:ca661e7520de
64 changeset: 3:ca661e7520de
64 tag: ?
65 tag: ?
65 user: test
66 user: test
66 date: Thu Jan 01 00:00:00 1970 +0000
67 date: Thu Jan 01 00:00:00 1970 +0000
67 summary: utf-8 e' encoded: ?
68 summary: utf-8 e' encoded: ?
68
69
69 changeset: 2:650c6f3d55dd
70 changeset: 2:650c6f3d55dd
70 user: test
71 user: test
71 date: Thu Jan 01 00:00:00 1970 +0000
72 date: Thu Jan 01 00:00:00 1970 +0000
72 summary: latin-1 e' encoded: ?
73 summary: latin-1 e' encoded: ?
73
74
74 changeset: 1:0e5b7e3f9c4a
75 changeset: 1:0e5b7e3f9c4a
75 user: test
76 user: test
76 date: Mon Jan 12 13:46:40 1970 +0000
77 date: Mon Jan 12 13:46:40 1970 +0000
77 summary: koi8-r: ????? = u'\u0440\u0442\u0443\u0442\u044c'
78 summary: koi8-r: ????? = u'\u0440\u0442\u0443\u0442\u044c'
78
79
79 changeset: 0:1e78a93102a3
80 changeset: 0:1e78a93102a3
80 user: test
81 user: test
81 date: Mon Jan 12 13:46:40 1970 +0000
82 date: Mon Jan 12 13:46:40 1970 +0000
82 summary: latin-1 e': ? = u'\xe9'
83 summary: latin-1 e': ? = u'\xe9'
83
84
84
85
85 hg log (latin-1)
86 hg log (latin-1)
86
87
87 $ hg --encoding latin-1 log
88 $ hg --encoding latin-1 log
88 changeset: 5:a52c0692f24a
89 changeset: 5:a52c0692f24a
89 branch: \xe9 (esc)
90 branch: \xe9 (esc)
90 tag: tip
91 tag: tip
91 user: test
92 user: test
92 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
93 summary: latin1 branch
94 summary: latin1 branch
94
95
95 changeset: 4:94db611b4196
96 changeset: 4:94db611b4196
96 user: test
97 user: test
97 date: Thu Jan 01 00:00:00 1970 +0000
98 date: Thu Jan 01 00:00:00 1970 +0000
98 summary: Added tag \xe9 for changeset ca661e7520de (esc)
99 summary: Added tag \xe9 for changeset ca661e7520de (esc)
99
100
100 changeset: 3:ca661e7520de
101 changeset: 3:ca661e7520de
101 tag: \xe9 (esc)
102 tag: \xe9 (esc)
102 user: test
103 user: test
103 date: Thu Jan 01 00:00:00 1970 +0000
104 date: Thu Jan 01 00:00:00 1970 +0000
104 summary: utf-8 e' encoded: \xe9 (esc)
105 summary: utf-8 e' encoded: \xe9 (esc)
105
106
106 changeset: 2:650c6f3d55dd
107 changeset: 2:650c6f3d55dd
107 user: test
108 user: test
108 date: Thu Jan 01 00:00:00 1970 +0000
109 date: Thu Jan 01 00:00:00 1970 +0000
109 summary: latin-1 e' encoded: \xe9 (esc)
110 summary: latin-1 e' encoded: \xe9 (esc)
110
111
111 changeset: 1:0e5b7e3f9c4a
112 changeset: 1:0e5b7e3f9c4a
112 user: test
113 user: test
113 date: Mon Jan 12 13:46:40 1970 +0000
114 date: Mon Jan 12 13:46:40 1970 +0000
114 summary: koi8-r: \xd2\xd4\xd5\xd4\xd8 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
115 summary: koi8-r: \xd2\xd4\xd5\xd4\xd8 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
115
116
116 changeset: 0:1e78a93102a3
117 changeset: 0:1e78a93102a3
117 user: test
118 user: test
118 date: Mon Jan 12 13:46:40 1970 +0000
119 date: Mon Jan 12 13:46:40 1970 +0000
119 summary: latin-1 e': \xe9 = u'\\xe9' (esc)
120 summary: latin-1 e': \xe9 = u'\\xe9' (esc)
120
121
121
122
122 hg log (utf-8)
123 hg log (utf-8)
123
124
124 $ hg --encoding utf-8 log
125 $ hg --encoding utf-8 log
125 changeset: 5:a52c0692f24a
126 changeset: 5:a52c0692f24a
126 branch: \xc3\xa9 (esc)
127 branch: \xc3\xa9 (esc)
127 tag: tip
128 tag: tip
128 user: test
129 user: test
129 date: Thu Jan 01 00:00:00 1970 +0000
130 date: Thu Jan 01 00:00:00 1970 +0000
130 summary: latin1 branch
131 summary: latin1 branch
131
132
132 changeset: 4:94db611b4196
133 changeset: 4:94db611b4196
133 user: test
134 user: test
134 date: Thu Jan 01 00:00:00 1970 +0000
135 date: Thu Jan 01 00:00:00 1970 +0000
135 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
136 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
136
137
137 changeset: 3:ca661e7520de
138 changeset: 3:ca661e7520de
138 tag: \xc3\xa9 (esc)
139 tag: \xc3\xa9 (esc)
139 user: test
140 user: test
140 date: Thu Jan 01 00:00:00 1970 +0000
141 date: Thu Jan 01 00:00:00 1970 +0000
141 summary: utf-8 e' encoded: \xc3\xa9 (esc)
142 summary: utf-8 e' encoded: \xc3\xa9 (esc)
142
143
143 changeset: 2:650c6f3d55dd
144 changeset: 2:650c6f3d55dd
144 user: test
145 user: test
145 date: Thu Jan 01 00:00:00 1970 +0000
146 date: Thu Jan 01 00:00:00 1970 +0000
146 summary: latin-1 e' encoded: \xc3\xa9 (esc)
147 summary: latin-1 e' encoded: \xc3\xa9 (esc)
147
148
148 changeset: 1:0e5b7e3f9c4a
149 changeset: 1:0e5b7e3f9c4a
149 user: test
150 user: test
150 date: Mon Jan 12 13:46:40 1970 +0000
151 date: Mon Jan 12 13:46:40 1970 +0000
151 summary: koi8-r: \xc3\x92\xc3\x94\xc3\x95\xc3\x94\xc3\x98 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
152 summary: koi8-r: \xc3\x92\xc3\x94\xc3\x95\xc3\x94\xc3\x98 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
152
153
153 changeset: 0:1e78a93102a3
154 changeset: 0:1e78a93102a3
154 user: test
155 user: test
155 date: Mon Jan 12 13:46:40 1970 +0000
156 date: Mon Jan 12 13:46:40 1970 +0000
156 summary: latin-1 e': \xc3\xa9 = u'\\xe9' (esc)
157 summary: latin-1 e': \xc3\xa9 = u'\\xe9' (esc)
157
158
158
159
159 hg tags (ascii)
160 hg tags (ascii)
160
161
161 $ HGENCODING=ascii hg tags
162 $ HGENCODING=ascii hg tags
162 tip 5:a52c0692f24a
163 tip 5:a52c0692f24a
163 ? 3:ca661e7520de
164 ? 3:ca661e7520de
164
165
165 hg tags (latin-1)
166 hg tags (latin-1)
166
167
167 $ HGENCODING=latin-1 hg tags
168 $ HGENCODING=latin-1 hg tags
168 tip 5:a52c0692f24a
169 tip 5:a52c0692f24a
169 \xe9 3:ca661e7520de (esc)
170 \xe9 3:ca661e7520de (esc)
170
171
171 hg tags (utf-8)
172 hg tags (utf-8)
172
173
173 $ HGENCODING=utf-8 hg tags
174 $ HGENCODING=utf-8 hg tags
174 tip 5:a52c0692f24a
175 tip 5:a52c0692f24a
175 \xc3\xa9 3:ca661e7520de (esc)
176 \xc3\xa9 3:ca661e7520de (esc)
176
177
177 hg branches (ascii)
178 hg branches (ascii)
178
179
179 $ HGENCODING=ascii hg branches
180 $ HGENCODING=ascii hg branches
180 ? 5:a52c0692f24a
181 ? 5:a52c0692f24a
181 default 4:94db611b4196 (inactive)
182 default 4:94db611b4196 (inactive)
182
183
183 hg branches (latin-1)
184 hg branches (latin-1)
184
185
185 $ HGENCODING=latin-1 hg branches
186 $ HGENCODING=latin-1 hg branches
186 \xe9 5:a52c0692f24a (esc)
187 \xe9 5:a52c0692f24a (esc)
187 default 4:94db611b4196 (inactive)
188 default 4:94db611b4196 (inactive)
188
189
189 hg branches (utf-8)
190 hg branches (utf-8)
190
191
191 $ HGENCODING=utf-8 hg branches
192 $ HGENCODING=utf-8 hg branches
192 \xc3\xa9 5:a52c0692f24a (esc)
193 \xc3\xa9 5:a52c0692f24a (esc)
193 default 4:94db611b4196 (inactive)
194 default 4:94db611b4196 (inactive)
194 $ echo '[ui]' >> .hg/hgrc
195 $ echo '[ui]' >> .hg/hgrc
195 $ echo 'fallbackencoding = koi8-r' >> .hg/hgrc
196 $ echo 'fallbackencoding = koi8-r' >> .hg/hgrc
196
197
197 hg log (utf-8)
198 hg log (utf-8)
198
199
199 $ HGENCODING=utf-8 hg log
200 $ HGENCODING=utf-8 hg log
200 changeset: 5:a52c0692f24a
201 changeset: 5:a52c0692f24a
201 branch: \xc3\xa9 (esc)
202 branch: \xc3\xa9 (esc)
202 tag: tip
203 tag: tip
203 user: test
204 user: test
204 date: Thu Jan 01 00:00:00 1970 +0000
205 date: Thu Jan 01 00:00:00 1970 +0000
205 summary: latin1 branch
206 summary: latin1 branch
206
207
207 changeset: 4:94db611b4196
208 changeset: 4:94db611b4196
208 user: test
209 user: test
209 date: Thu Jan 01 00:00:00 1970 +0000
210 date: Thu Jan 01 00:00:00 1970 +0000
210 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
211 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
211
212
212 changeset: 3:ca661e7520de
213 changeset: 3:ca661e7520de
213 tag: \xc3\xa9 (esc)
214 tag: \xc3\xa9 (esc)
214 user: test
215 user: test
215 date: Thu Jan 01 00:00:00 1970 +0000
216 date: Thu Jan 01 00:00:00 1970 +0000
216 summary: utf-8 e' encoded: \xc3\xa9 (esc)
217 summary: utf-8 e' encoded: \xc3\xa9 (esc)
217
218
218 changeset: 2:650c6f3d55dd
219 changeset: 2:650c6f3d55dd
219 user: test
220 user: test
220 date: Thu Jan 01 00:00:00 1970 +0000
221 date: Thu Jan 01 00:00:00 1970 +0000
221 summary: latin-1 e' encoded: \xc3\xa9 (esc)
222 summary: latin-1 e' encoded: \xc3\xa9 (esc)
222
223
223 changeset: 1:0e5b7e3f9c4a
224 changeset: 1:0e5b7e3f9c4a
224 user: test
225 user: test
225 date: Mon Jan 12 13:46:40 1970 +0000
226 date: Mon Jan 12 13:46:40 1970 +0000
226 summary: koi8-r: \xd1\x80\xd1\x82\xd1\x83\xd1\x82\xd1\x8c = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
227 summary: koi8-r: \xd1\x80\xd1\x82\xd1\x83\xd1\x82\xd1\x8c = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
227
228
228 changeset: 0:1e78a93102a3
229 changeset: 0:1e78a93102a3
229 user: test
230 user: test
230 date: Mon Jan 12 13:46:40 1970 +0000
231 date: Mon Jan 12 13:46:40 1970 +0000
231 summary: latin-1 e': \xd0\x98 = u'\\xe9' (esc)
232 summary: latin-1 e': \xd0\x98 = u'\\xe9' (esc)
232
233
233
234
234 hg log (dolphin)
235 hg log (dolphin)
235
236
236 $ HGENCODING=dolphin hg log
237 $ HGENCODING=dolphin hg log
237 abort: unknown encoding: dolphin, please check your locale settings
238 abort: unknown encoding: dolphin, please check your locale settings
238 [255]
239 [255]
239 $ HGENCODING=ascii hg branch `cat latin-1-tag`
240 $ HGENCODING=ascii hg branch `cat latin-1-tag`
240 abort: decoding near '\xe9': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! (esc)
241 abort: decoding near '\xe9': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! (esc)
241 [255]
242 [255]
242 $ cp latin-1-tag .hg/branch
243 $ cp latin-1-tag .hg/branch
243 $ HGENCODING=latin-1 hg ci -m 'auto-promote legacy name'
244 $ HGENCODING=latin-1 hg ci -m 'auto-promote legacy name'
244
245
245 Test roundtrip encoding of lookup tables when not using UTF-8 (issue2763)
246 Test roundtrip encoding of lookup tables when not using UTF-8 (issue2763)
246
247
247 $ HGENCODING=latin-1 hg up `cat latin-1-tag`
248 $ HGENCODING=latin-1 hg up `cat latin-1-tag`
248 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
249 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
249
250
@@ -1,407 +1,412 b''
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "fetch=" >> $HGRCPATH
4 $ echo "fetch=" >> $HGRCPATH
5
5
6 test fetch with default branches only
6 test fetch with default branches only
7
7
8 $ hg init a
8 $ hg init a
9 $ echo a > a/a
9 $ echo a > a/a
10 $ hg --cwd a commit -Ama
10 $ hg --cwd a commit -Ama
11 adding a
11 adding a
12 $ hg clone a b
12 $ hg clone a b
13 updating to branch default
13 updating to branch default
14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 $ hg clone a c
15 $ hg clone a c
16 updating to branch default
16 updating to branch default
17 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
18 $ echo b > a/b
18 $ echo b > a/b
19 $ hg --cwd a commit -Amb
19 $ hg --cwd a commit -Amb
20 adding b
20 adding b
21 $ hg --cwd a parents -q
21 $ hg --cwd a parents -q
22 1:d2ae7f538514
22 1:d2ae7f538514
23
23
24 should pull one change
24 should pull one change
25
25
26 $ hg --cwd b fetch ../a
26 $ hg --cwd b fetch ../a
27 pulling from ../a
27 pulling from ../a
28 searching for changes
28 searching for changes
29 adding changesets
29 adding changesets
30 adding manifests
30 adding manifests
31 adding file changes
31 adding file changes
32 added 1 changesets with 1 changes to 1 files
32 added 1 changesets with 1 changes to 1 files
33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 $ hg --cwd b parents -q
34 $ hg --cwd b parents -q
35 1:d2ae7f538514
35 1:d2ae7f538514
36 $ echo c > c/c
36 $ echo c > c/c
37 $ hg --cwd c commit -Amc
37 $ hg --cwd c commit -Amc
38 adding c
38 adding c
39 $ hg clone c d
39 $ hg clone c d
40 updating to branch default
40 updating to branch default
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 $ hg clone c e
42 $ hg clone c e
43 updating to branch default
43 updating to branch default
44 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
45
45
46 We cannot use the default commit message if fetching from a local
46 We cannot use the default commit message if fetching from a local
47 repo, because the path of the repo will be included in the commit
47 repo, because the path of the repo will be included in the commit
48 message, making every commit appear different.
48 message, making every commit appear different.
49 should merge c into a
49 should merge c into a
50
50
51 $ hg --cwd c fetch -d '0 0' -m 'automated merge' ../a
51 $ hg --cwd c fetch -d '0 0' -m 'automated merge' ../a
52 pulling from ../a
52 pulling from ../a
53 searching for changes
53 searching for changes
54 adding changesets
54 adding changesets
55 adding manifests
55 adding manifests
56 adding file changes
56 adding file changes
57 added 1 changesets with 1 changes to 1 files (+1 heads)
57 added 1 changesets with 1 changes to 1 files (+1 heads)
58 updating to 2:d2ae7f538514
58 updating to 2:d2ae7f538514
59 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
59 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
60 merging with 1:d36c0562f908
60 merging with 1:d36c0562f908
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 new changeset 3:a323a0c43ec4 merges remote changes with local
62 new changeset 3:a323a0c43ec4 merges remote changes with local
63 $ ls c
63 $ ls c
64 a
64 a
65 b
65 b
66 c
66 c
67 $ hg --cwd a serve -a localhost -p $HGPORT -d --pid-file=hg.pid
67 $ hg --cwd a serve -a localhost -p $HGPORT -d --pid-file=hg.pid
68 $ cat a/hg.pid >> "$DAEMON_PIDS"
68 $ cat a/hg.pid >> "$DAEMON_PIDS"
69
69
70 fetch over http, no auth
70 fetch over http, no auth
71
71
72 $ hg --cwd d fetch http://localhost:$HGPORT/
72 $ hg --cwd d fetch http://localhost:$HGPORT/
73 pulling from http://localhost:$HGPORT/
73 pulling from http://localhost:$HGPORT/
74 searching for changes
74 searching for changes
75 adding changesets
75 adding changesets
76 adding manifests
76 adding manifests
77 adding file changes
77 adding file changes
78 added 1 changesets with 1 changes to 1 files (+1 heads)
78 added 1 changesets with 1 changes to 1 files (+1 heads)
79 updating to 2:d2ae7f538514
79 updating to 2:d2ae7f538514
80 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
80 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
81 merging with 1:d36c0562f908
81 merging with 1:d36c0562f908
82 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 new changeset 3:* merges remote changes with local (glob)
83 new changeset 3:* merges remote changes with local (glob)
84 $ hg --cwd d tip --template '{desc}\n'
84 $ hg --cwd d tip --template '{desc}\n'
85 Automated merge with http://localhost:$HGPORT/
85 Automated merge with http://localhost:$HGPORT/
86
86
87 fetch over http with auth (should be hidden in desc)
87 fetch over http with auth (should be hidden in desc)
88
88
89 $ hg --cwd e fetch http://user:password@localhost:$HGPORT/
89 $ hg --cwd e fetch http://user:password@localhost:$HGPORT/
90 pulling from http://user:***@localhost:$HGPORT/
90 pulling from http://user:***@localhost:$HGPORT/
91 searching for changes
91 searching for changes
92 adding changesets
92 adding changesets
93 adding manifests
93 adding manifests
94 adding file changes
94 adding file changes
95 added 1 changesets with 1 changes to 1 files (+1 heads)
95 added 1 changesets with 1 changes to 1 files (+1 heads)
96 updating to 2:d2ae7f538514
96 updating to 2:d2ae7f538514
97 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
97 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
98 merging with 1:d36c0562f908
98 merging with 1:d36c0562f908
99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 new changeset 3:* merges remote changes with local (glob)
100 new changeset 3:* merges remote changes with local (glob)
101 $ hg --cwd e tip --template '{desc}\n'
101 $ hg --cwd e tip --template '{desc}\n'
102 Automated merge with http://localhost:$HGPORT/
102 Automated merge with http://localhost:$HGPORT/
103 $ hg clone a f
103 $ hg clone a f
104 updating to branch default
104 updating to branch default
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 $ hg clone a g
106 $ hg clone a g
107 updating to branch default
107 updating to branch default
108 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 $ echo f > f/f
109 $ echo f > f/f
110 $ hg --cwd f ci -Amf
110 $ hg --cwd f ci -Amf
111 adding f
111 adding f
112 $ echo g > g/g
112 $ echo g > g/g
113 $ hg --cwd g ci -Amg
113 $ hg --cwd g ci -Amg
114 adding g
114 adding g
115 $ hg clone -q f h
115 $ hg clone -q f h
116 $ hg clone -q g i
116 $ hg clone -q g i
117
117
118 should merge f into g
118 should merge f into g
119
119
120 $ hg --cwd g fetch -d '0 0' --switch -m 'automated merge' ../f
120 $ hg --cwd g fetch -d '0 0' --switch -m 'automated merge' ../f
121 pulling from ../f
121 pulling from ../f
122 searching for changes
122 searching for changes
123 adding changesets
123 adding changesets
124 adding manifests
124 adding manifests
125 adding file changes
125 adding file changes
126 added 1 changesets with 1 changes to 1 files (+1 heads)
126 added 1 changesets with 1 changes to 1 files (+1 heads)
127 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
128 merging with 3:6343ca3eff20
128 merging with 3:6343ca3eff20
129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
130 new changeset 4:f7faa0b7d3c6 merges remote changes with local
130 new changeset 4:f7faa0b7d3c6 merges remote changes with local
131 $ rm i/g
131 $ rm i/g
132
132
133 should abort, because i is modified
133 should abort, because i is modified
134
134
135 $ hg --cwd i fetch ../h
135 $ hg --cwd i fetch ../h
136 abort: working directory is missing some files
136 abort: working directory is missing some files
137 [255]
137 [255]
138
138
139 test fetch with named branches
139 test fetch with named branches
140
140
141 $ hg init nbase
141 $ hg init nbase
142 $ echo base > nbase/a
142 $ echo base > nbase/a
143 $ hg -R nbase ci -Am base
143 $ hg -R nbase ci -Am base
144 adding a
144 adding a
145 $ hg -R nbase branch a
145 $ hg -R nbase branch a
146 marked working directory as branch a
146 marked working directory as branch a
147 (branches are permanent and global, did you want a bookmark?)
147 $ echo a > nbase/a
148 $ echo a > nbase/a
148 $ hg -R nbase ci -m a
149 $ hg -R nbase ci -m a
149 $ hg -R nbase up -C 0
150 $ hg -R nbase up -C 0
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 $ hg -R nbase branch b
152 $ hg -R nbase branch b
152 marked working directory as branch b
153 marked working directory as branch b
154 (branches are permanent and global, did you want a bookmark?)
153 $ echo b > nbase/b
155 $ echo b > nbase/b
154 $ hg -R nbase ci -Am b
156 $ hg -R nbase ci -Am b
155 adding b
157 adding b
156
158
157 pull in change on foreign branch
159 pull in change on foreign branch
158
160
159 $ hg clone nbase n1
161 $ hg clone nbase n1
160 updating to branch default
162 updating to branch default
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 $ hg clone nbase n2
164 $ hg clone nbase n2
163 updating to branch default
165 updating to branch default
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
166 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 $ hg -R n1 up -C a
167 $ hg -R n1 up -C a
166 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
167 $ echo aa > n1/a
169 $ echo aa > n1/a
168 $ hg -R n1 ci -m a1
170 $ hg -R n1 ci -m a1
169 $ hg -R n2 up -C b
171 $ hg -R n2 up -C b
170 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 $ hg -R n2 fetch -m 'merge' n1
173 $ hg -R n2 fetch -m 'merge' n1
172 pulling from n1
174 pulling from n1
173 searching for changes
175 searching for changes
174 adding changesets
176 adding changesets
175 adding manifests
177 adding manifests
176 adding file changes
178 adding file changes
177 added 1 changesets with 1 changes to 1 files
179 added 1 changesets with 1 changes to 1 files
178
180
179 parent should be 2 (no automatic update)
181 parent should be 2 (no automatic update)
180
182
181 $ hg -R n2 parents --template '{rev}\n'
183 $ hg -R n2 parents --template '{rev}\n'
182 2
184 2
183 $ rm -fr n1 n2
185 $ rm -fr n1 n2
184
186
185 pull in changes on both foreign and local branches
187 pull in changes on both foreign and local branches
186
188
187 $ hg clone nbase n1
189 $ hg clone nbase n1
188 updating to branch default
190 updating to branch default
189 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
190 $ hg clone nbase n2
192 $ hg clone nbase n2
191 updating to branch default
193 updating to branch default
192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 $ hg -R n1 up -C a
195 $ hg -R n1 up -C a
194 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
195 $ echo aa > n1/a
197 $ echo aa > n1/a
196 $ hg -R n1 ci -m a1
198 $ hg -R n1 ci -m a1
197 $ hg -R n1 up -C b
199 $ hg -R n1 up -C b
198 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
200 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 $ echo bb > n1/b
201 $ echo bb > n1/b
200 $ hg -R n1 ci -m b1
202 $ hg -R n1 ci -m b1
201 $ hg -R n2 up -C b
203 $ hg -R n2 up -C b
202 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 $ hg -R n2 fetch -m 'merge' n1
205 $ hg -R n2 fetch -m 'merge' n1
204 pulling from n1
206 pulling from n1
205 searching for changes
207 searching for changes
206 adding changesets
208 adding changesets
207 adding manifests
209 adding manifests
208 adding file changes
210 adding file changes
209 added 2 changesets with 2 changes to 2 files
211 added 2 changesets with 2 changes to 2 files
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
211
213
212 parent should be 4 (fast forward)
214 parent should be 4 (fast forward)
213
215
214 $ hg -R n2 parents --template '{rev}\n'
216 $ hg -R n2 parents --template '{rev}\n'
215 4
217 4
216 $ rm -fr n1 n2
218 $ rm -fr n1 n2
217
219
218 pull changes on foreign (2 new heads) and local (1 new head) branches
220 pull changes on foreign (2 new heads) and local (1 new head) branches
219 with a local change
221 with a local change
220
222
221 $ hg clone nbase n1
223 $ hg clone nbase n1
222 updating to branch default
224 updating to branch default
223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 $ hg clone nbase n2
226 $ hg clone nbase n2
225 updating to branch default
227 updating to branch default
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
227 $ hg -R n1 up -C a
229 $ hg -R n1 up -C a
228 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
229 $ echo a1 > n1/a
231 $ echo a1 > n1/a
230 $ hg -R n1 ci -m a1
232 $ hg -R n1 ci -m a1
231 $ hg -R n1 up -C b
233 $ hg -R n1 up -C b
232 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
234 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 $ echo bb > n1/b
235 $ echo bb > n1/b
234 $ hg -R n1 ci -m b1
236 $ hg -R n1 ci -m b1
235 $ hg -R n1 up -C 1
237 $ hg -R n1 up -C 1
236 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
238 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
237 $ echo a2 > n1/a
239 $ echo a2 > n1/a
238 $ hg -R n1 ci -m a2
240 $ hg -R n1 ci -m a2
239 created new head
241 created new head
240 $ hg -R n2 up -C b
242 $ hg -R n2 up -C b
241 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
243 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
242 $ echo change >> n2/c
244 $ echo change >> n2/c
243 $ hg -R n2 ci -A -m local
245 $ hg -R n2 ci -A -m local
244 adding c
246 adding c
245 $ hg -R n2 fetch -d '0 0' -m 'merge' n1
247 $ hg -R n2 fetch -d '0 0' -m 'merge' n1
246 pulling from n1
248 pulling from n1
247 searching for changes
249 searching for changes
248 adding changesets
250 adding changesets
249 adding manifests
251 adding manifests
250 adding file changes
252 adding file changes
251 added 3 changesets with 3 changes to 2 files (+2 heads)
253 added 3 changesets with 3 changes to 2 files (+2 heads)
252 updating to 5:3c4a837a864f
254 updating to 5:3c4a837a864f
253 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
255 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
254 merging with 3:1267f84a9ea5
256 merging with 3:1267f84a9ea5
255 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 new changeset 7:2cf2a1261f21 merges remote changes with local
258 new changeset 7:2cf2a1261f21 merges remote changes with local
257
259
258 parent should be 7 (new merge changeset)
260 parent should be 7 (new merge changeset)
259
261
260 $ hg -R n2 parents --template '{rev}\n'
262 $ hg -R n2 parents --template '{rev}\n'
261 7
263 7
262 $ rm -fr n1 n2
264 $ rm -fr n1 n2
263
265
264 pull in changes on foreign (merge of local branch) and local (2 new
266 pull in changes on foreign (merge of local branch) and local (2 new
265 heads) with a local change
267 heads) with a local change
266
268
267 $ hg clone nbase n1
269 $ hg clone nbase n1
268 updating to branch default
270 updating to branch default
269 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
270 $ hg clone nbase n2
272 $ hg clone nbase n2
271 updating to branch default
273 updating to branch default
272 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
273 $ hg -R n1 up -C a
275 $ hg -R n1 up -C a
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 $ hg -R n1 merge b
277 $ hg -R n1 merge b
276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 (branch merge, don't forget to commit)
279 (branch merge, don't forget to commit)
278 $ hg -R n1 ci -m merge
280 $ hg -R n1 ci -m merge
279 $ hg -R n1 up -C 2
281 $ hg -R n1 up -C 2
280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
282 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
281 $ echo c > n1/a
283 $ echo c > n1/a
282 $ hg -R n1 ci -m c
284 $ hg -R n1 ci -m c
283 $ hg -R n1 up -C 2
285 $ hg -R n1 up -C 2
284 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
286 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
285 $ echo cc > n1/a
287 $ echo cc > n1/a
286 $ hg -R n1 ci -m cc
288 $ hg -R n1 ci -m cc
287 created new head
289 created new head
288 $ hg -R n2 up -C b
290 $ hg -R n2 up -C b
289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 $ echo change >> n2/b
292 $ echo change >> n2/b
291 $ hg -R n2 ci -A -m local
293 $ hg -R n2 ci -A -m local
292 $ hg -R n2 fetch -m 'merge' n1
294 $ hg -R n2 fetch -m 'merge' n1
293 pulling from n1
295 pulling from n1
294 searching for changes
296 searching for changes
295 adding changesets
297 adding changesets
296 adding manifests
298 adding manifests
297 adding file changes
299 adding file changes
298 added 3 changesets with 2 changes to 1 files (+2 heads)
300 added 3 changesets with 2 changes to 1 files (+2 heads)
299 not merging with 1 other new branch heads (use "hg heads ." and "hg merge" to merge them)
301 not merging with 1 other new branch heads (use "hg heads ." and "hg merge" to merge them)
300 [1]
302 [1]
301
303
302 parent should be 3 (fetch did not merge anything)
304 parent should be 3 (fetch did not merge anything)
303
305
304 $ hg -R n2 parents --template '{rev}\n'
306 $ hg -R n2 parents --template '{rev}\n'
305 3
307 3
306 $ rm -fr n1 n2
308 $ rm -fr n1 n2
307
309
308 pull in change on different branch than dirstate
310 pull in change on different branch than dirstate
309
311
310 $ hg init n1
312 $ hg init n1
311 $ echo a > n1/a
313 $ echo a > n1/a
312 $ hg -R n1 ci -Am initial
314 $ hg -R n1 ci -Am initial
313 adding a
315 adding a
314 $ hg clone n1 n2
316 $ hg clone n1 n2
315 updating to branch default
317 updating to branch default
316 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
317 $ echo b > n1/a
319 $ echo b > n1/a
318 $ hg -R n1 ci -m next
320 $ hg -R n1 ci -m next
319 $ hg -R n2 branch topic
321 $ hg -R n2 branch topic
320 marked working directory as branch topic
322 marked working directory as branch topic
323 (branches are permanent and global, did you want a bookmark?)
321 $ hg -R n2 fetch -m merge n1
324 $ hg -R n2 fetch -m merge n1
322 abort: working dir not at branch tip (use "hg update" to check out branch tip)
325 abort: working dir not at branch tip (use "hg update" to check out branch tip)
323 [255]
326 [255]
324
327
325 parent should be 0 (fetch did not update or merge anything)
328 parent should be 0 (fetch did not update or merge anything)
326
329
327 $ hg -R n2 parents --template '{rev}\n'
330 $ hg -R n2 parents --template '{rev}\n'
328 0
331 0
329 $ rm -fr n1 n2
332 $ rm -fr n1 n2
330
333
331 test fetch with inactive branches
334 test fetch with inactive branches
332
335
333 $ hg init ib1
336 $ hg init ib1
334 $ echo a > ib1/a
337 $ echo a > ib1/a
335 $ hg --cwd ib1 ci -Am base
338 $ hg --cwd ib1 ci -Am base
336 adding a
339 adding a
337 $ hg --cwd ib1 branch second
340 $ hg --cwd ib1 branch second
338 marked working directory as branch second
341 marked working directory as branch second
342 (branches are permanent and global, did you want a bookmark?)
339 $ echo b > ib1/b
343 $ echo b > ib1/b
340 $ hg --cwd ib1 ci -Am onsecond
344 $ hg --cwd ib1 ci -Am onsecond
341 adding b
345 adding b
342 $ hg --cwd ib1 branch -f default
346 $ hg --cwd ib1 branch -f default
343 marked working directory as branch default
347 marked working directory as branch default
348 (branches are permanent and global, did you want a bookmark?)
344 $ echo c > ib1/c
349 $ echo c > ib1/c
345 $ hg --cwd ib1 ci -Am newdefault
350 $ hg --cwd ib1 ci -Am newdefault
346 adding c
351 adding c
347 created new head
352 created new head
348 $ hg clone ib1 ib2
353 $ hg clone ib1 ib2
349 updating to branch default
354 updating to branch default
350 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
355 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
351
356
352 fetch should succeed
357 fetch should succeed
353
358
354 $ hg --cwd ib2 fetch ../ib1
359 $ hg --cwd ib2 fetch ../ib1
355 pulling from ../ib1
360 pulling from ../ib1
356 searching for changes
361 searching for changes
357 no changes found
362 no changes found
358 $ rm -fr ib1 ib2
363 $ rm -fr ib1 ib2
359
364
360 test issue1726
365 test issue1726
361
366
362 $ hg init i1726r1
367 $ hg init i1726r1
363 $ echo a > i1726r1/a
368 $ echo a > i1726r1/a
364 $ hg --cwd i1726r1 ci -Am base
369 $ hg --cwd i1726r1 ci -Am base
365 adding a
370 adding a
366 $ hg clone i1726r1 i1726r2
371 $ hg clone i1726r1 i1726r2
367 updating to branch default
372 updating to branch default
368 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
373 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
369 $ echo b > i1726r1/a
374 $ echo b > i1726r1/a
370 $ hg --cwd i1726r1 ci -m second
375 $ hg --cwd i1726r1 ci -m second
371 $ echo c > i1726r2/a
376 $ echo c > i1726r2/a
372 $ hg --cwd i1726r2 ci -m third
377 $ hg --cwd i1726r2 ci -m third
373 $ HGMERGE=true hg --cwd i1726r2 fetch ../i1726r1
378 $ HGMERGE=true hg --cwd i1726r2 fetch ../i1726r1
374 pulling from ../i1726r1
379 pulling from ../i1726r1
375 searching for changes
380 searching for changes
376 adding changesets
381 adding changesets
377 adding manifests
382 adding manifests
378 adding file changes
383 adding file changes
379 added 1 changesets with 1 changes to 1 files (+1 heads)
384 added 1 changesets with 1 changes to 1 files (+1 heads)
380 updating to 2:7837755a2789
385 updating to 2:7837755a2789
381 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
386 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 merging with 1:d1f0c6c48ebd
387 merging with 1:d1f0c6c48ebd
383 merging a
388 merging a
384 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
389 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
385 new changeset 3:* merges remote changes with local (glob)
390 new changeset 3:* merges remote changes with local (glob)
386 $ hg --cwd i1726r2 heads default --template '{rev}\n'
391 $ hg --cwd i1726r2 heads default --template '{rev}\n'
387 3
392 3
388
393
389 test issue2047
394 test issue2047
390
395
391 $ hg -q init i2047a
396 $ hg -q init i2047a
392 $ cd i2047a
397 $ cd i2047a
393 $ echo a > a
398 $ echo a > a
394 $ hg -q ci -Am a
399 $ hg -q ci -Am a
395 $ hg -q branch stable
400 $ hg -q branch stable
396 $ echo b > b
401 $ echo b > b
397 $ hg -q ci -Am b
402 $ hg -q ci -Am b
398 $ cd ..
403 $ cd ..
399 $ hg -q clone -r 0 i2047a i2047b
404 $ hg -q clone -r 0 i2047a i2047b
400 $ cd i2047b
405 $ cd i2047b
401 $ hg fetch ../i2047a
406 $ hg fetch ../i2047a
402 pulling from ../i2047a
407 pulling from ../i2047a
403 searching for changes
408 searching for changes
404 adding changesets
409 adding changesets
405 adding manifests
410 adding manifests
406 adding file changes
411 adding file changes
407 added 1 changesets with 1 changes to 1 files
412 added 1 changesets with 1 changes to 1 files
@@ -1,1159 +1,1160 b''
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 An attempt at more fully testing the hgweb web interface.
3 An attempt at more fully testing the hgweb web interface.
4 The following things are tested elsewhere and are therefore omitted:
4 The following things are tested elsewhere and are therefore omitted:
5 - archive, tested in test-archive
5 - archive, tested in test-archive
6 - unbundle, tested in test-push-http
6 - unbundle, tested in test-push-http
7 - changegroupsubset, tested in test-pull
7 - changegroupsubset, tested in test-pull
8
8
9 Set up the repo
9 Set up the repo
10
10
11 $ hg init test
11 $ hg init test
12 $ cd test
12 $ cd test
13 $ mkdir da
13 $ mkdir da
14 $ echo foo > da/foo
14 $ echo foo > da/foo
15 $ echo foo > foo
15 $ echo foo > foo
16 $ hg ci -Ambase
16 $ hg ci -Ambase
17 adding da/foo
17 adding da/foo
18 adding foo
18 adding foo
19 $ hg tag 1.0
19 $ hg tag 1.0
20 $ hg bookmark something
20 $ hg bookmark something
21 $ hg bookmark -r0 anotherthing
21 $ hg bookmark -r0 anotherthing
22 $ echo another > foo
22 $ echo another > foo
23 $ hg branch stable
23 $ hg branch stable
24 marked working directory as branch stable
24 marked working directory as branch stable
25 (branches are permanent and global, did you want a bookmark?)
25 $ hg ci -Ambranch
26 $ hg ci -Ambranch
26 $ hg serve --config server.uncompressed=False -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
27 $ hg serve --config server.uncompressed=False -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
27 $ cat hg.pid >> $DAEMON_PIDS
28 $ cat hg.pid >> $DAEMON_PIDS
28
29
29 Logs and changes
30 Logs and changes
30
31
31 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom'
32 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom'
32 200 Script output follows
33 200 Script output follows
33
34
34 <?xml version="1.0" encoding="ascii"?>
35 <?xml version="1.0" encoding="ascii"?>
35 <feed xmlns="http://www.w3.org/2005/Atom">
36 <feed xmlns="http://www.w3.org/2005/Atom">
36 <!-- Changelog -->
37 <!-- Changelog -->
37 <id>http://*:$HGPORT/</id> (glob)
38 <id>http://*:$HGPORT/</id> (glob)
38 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
39 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
39 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
40 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
40 <title>test Changelog</title>
41 <title>test Changelog</title>
41 <updated>1970-01-01T00:00:00+00:00</updated>
42 <updated>1970-01-01T00:00:00+00:00</updated>
42
43
43 <entry>
44 <entry>
44 <title>branch</title>
45 <title>branch</title>
45 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
46 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
46 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
47 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
47 <author>
48 <author>
48 <name>test</name>
49 <name>test</name>
49 <email>&#116;&#101;&#115;&#116;</email>
50 <email>&#116;&#101;&#115;&#116;</email>
50 </author>
51 </author>
51 <updated>1970-01-01T00:00:00+00:00</updated>
52 <updated>1970-01-01T00:00:00+00:00</updated>
52 <published>1970-01-01T00:00:00+00:00</published>
53 <published>1970-01-01T00:00:00+00:00</published>
53 <content type="xhtml">
54 <content type="xhtml">
54 <div xmlns="http://www.w3.org/1999/xhtml">
55 <div xmlns="http://www.w3.org/1999/xhtml">
55 <pre xml:space="preserve">branch</pre>
56 <pre xml:space="preserve">branch</pre>
56 </div>
57 </div>
57 </content>
58 </content>
58 </entry>
59 </entry>
59 <entry>
60 <entry>
60 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
61 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
61 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
62 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
62 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
63 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
63 <author>
64 <author>
64 <name>test</name>
65 <name>test</name>
65 <email>&#116;&#101;&#115;&#116;</email>
66 <email>&#116;&#101;&#115;&#116;</email>
66 </author>
67 </author>
67 <updated>1970-01-01T00:00:00+00:00</updated>
68 <updated>1970-01-01T00:00:00+00:00</updated>
68 <published>1970-01-01T00:00:00+00:00</published>
69 <published>1970-01-01T00:00:00+00:00</published>
69 <content type="xhtml">
70 <content type="xhtml">
70 <div xmlns="http://www.w3.org/1999/xhtml">
71 <div xmlns="http://www.w3.org/1999/xhtml">
71 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
72 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
72 </div>
73 </div>
73 </content>
74 </content>
74 </entry>
75 </entry>
75 <entry>
76 <entry>
76 <title>base</title>
77 <title>base</title>
77 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
78 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
78 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
79 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
79 <author>
80 <author>
80 <name>test</name>
81 <name>test</name>
81 <email>&#116;&#101;&#115;&#116;</email>
82 <email>&#116;&#101;&#115;&#116;</email>
82 </author>
83 </author>
83 <updated>1970-01-01T00:00:00+00:00</updated>
84 <updated>1970-01-01T00:00:00+00:00</updated>
84 <published>1970-01-01T00:00:00+00:00</published>
85 <published>1970-01-01T00:00:00+00:00</published>
85 <content type="xhtml">
86 <content type="xhtml">
86 <div xmlns="http://www.w3.org/1999/xhtml">
87 <div xmlns="http://www.w3.org/1999/xhtml">
87 <pre xml:space="preserve">base</pre>
88 <pre xml:space="preserve">base</pre>
88 </div>
89 </div>
89 </content>
90 </content>
90 </entry>
91 </entry>
91
92
92 </feed>
93 </feed>
93 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom'
94 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom'
94 200 Script output follows
95 200 Script output follows
95
96
96 <?xml version="1.0" encoding="ascii"?>
97 <?xml version="1.0" encoding="ascii"?>
97 <feed xmlns="http://www.w3.org/2005/Atom">
98 <feed xmlns="http://www.w3.org/2005/Atom">
98 <!-- Changelog -->
99 <!-- Changelog -->
99 <id>http://*:$HGPORT/</id> (glob)
100 <id>http://*:$HGPORT/</id> (glob)
100 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
101 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
101 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
102 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
102 <title>test Changelog</title>
103 <title>test Changelog</title>
103 <updated>1970-01-01T00:00:00+00:00</updated>
104 <updated>1970-01-01T00:00:00+00:00</updated>
104
105
105 <entry>
106 <entry>
106 <title>branch</title>
107 <title>branch</title>
107 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
108 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
108 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
109 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
109 <author>
110 <author>
110 <name>test</name>
111 <name>test</name>
111 <email>&#116;&#101;&#115;&#116;</email>
112 <email>&#116;&#101;&#115;&#116;</email>
112 </author>
113 </author>
113 <updated>1970-01-01T00:00:00+00:00</updated>
114 <updated>1970-01-01T00:00:00+00:00</updated>
114 <published>1970-01-01T00:00:00+00:00</published>
115 <published>1970-01-01T00:00:00+00:00</published>
115 <content type="xhtml">
116 <content type="xhtml">
116 <div xmlns="http://www.w3.org/1999/xhtml">
117 <div xmlns="http://www.w3.org/1999/xhtml">
117 <pre xml:space="preserve">branch</pre>
118 <pre xml:space="preserve">branch</pre>
118 </div>
119 </div>
119 </content>
120 </content>
120 </entry>
121 </entry>
121 <entry>
122 <entry>
122 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
123 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
123 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
124 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
124 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
125 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
125 <author>
126 <author>
126 <name>test</name>
127 <name>test</name>
127 <email>&#116;&#101;&#115;&#116;</email>
128 <email>&#116;&#101;&#115;&#116;</email>
128 </author>
129 </author>
129 <updated>1970-01-01T00:00:00+00:00</updated>
130 <updated>1970-01-01T00:00:00+00:00</updated>
130 <published>1970-01-01T00:00:00+00:00</published>
131 <published>1970-01-01T00:00:00+00:00</published>
131 <content type="xhtml">
132 <content type="xhtml">
132 <div xmlns="http://www.w3.org/1999/xhtml">
133 <div xmlns="http://www.w3.org/1999/xhtml">
133 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
134 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
134 </div>
135 </div>
135 </content>
136 </content>
136 </entry>
137 </entry>
137 <entry>
138 <entry>
138 <title>base</title>
139 <title>base</title>
139 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
140 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
140 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
141 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
141 <author>
142 <author>
142 <name>test</name>
143 <name>test</name>
143 <email>&#116;&#101;&#115;&#116;</email>
144 <email>&#116;&#101;&#115;&#116;</email>
144 </author>
145 </author>
145 <updated>1970-01-01T00:00:00+00:00</updated>
146 <updated>1970-01-01T00:00:00+00:00</updated>
146 <published>1970-01-01T00:00:00+00:00</published>
147 <published>1970-01-01T00:00:00+00:00</published>
147 <content type="xhtml">
148 <content type="xhtml">
148 <div xmlns="http://www.w3.org/1999/xhtml">
149 <div xmlns="http://www.w3.org/1999/xhtml">
149 <pre xml:space="preserve">base</pre>
150 <pre xml:space="preserve">base</pre>
150 </div>
151 </div>
151 </content>
152 </content>
152 </entry>
153 </entry>
153
154
154 </feed>
155 </feed>
155 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom'
156 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom'
156 200 Script output follows
157 200 Script output follows
157
158
158 <?xml version="1.0" encoding="ascii"?>
159 <?xml version="1.0" encoding="ascii"?>
159 <feed xmlns="http://www.w3.org/2005/Atom">
160 <feed xmlns="http://www.w3.org/2005/Atom">
160 <id>http://*:$HGPORT/atom-log/tip/foo</id> (glob)
161 <id>http://*:$HGPORT/atom-log/tip/foo</id> (glob)
161 <link rel="self" href="http://*:$HGPORT/atom-log/tip/foo"/> (glob)
162 <link rel="self" href="http://*:$HGPORT/atom-log/tip/foo"/> (glob)
162 <title>test: foo history</title>
163 <title>test: foo history</title>
163 <updated>1970-01-01T00:00:00+00:00</updated>
164 <updated>1970-01-01T00:00:00+00:00</updated>
164
165
165 <entry>
166 <entry>
166 <title>base</title>
167 <title>base</title>
167 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
168 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
168 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
169 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
169 <author>
170 <author>
170 <name>test</name>
171 <name>test</name>
171 <email>&#116;&#101;&#115;&#116;</email>
172 <email>&#116;&#101;&#115;&#116;</email>
172 </author>
173 </author>
173 <updated>1970-01-01T00:00:00+00:00</updated>
174 <updated>1970-01-01T00:00:00+00:00</updated>
174 <published>1970-01-01T00:00:00+00:00</published>
175 <published>1970-01-01T00:00:00+00:00</published>
175 <content type="xhtml">
176 <content type="xhtml">
176 <div xmlns="http://www.w3.org/1999/xhtml">
177 <div xmlns="http://www.w3.org/1999/xhtml">
177 <pre xml:space="preserve">base</pre>
178 <pre xml:space="preserve">base</pre>
178 </div>
179 </div>
179 </content>
180 </content>
180 </entry>
181 </entry>
181
182
182 </feed>
183 </feed>
183 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/'
184 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/'
184 200 Script output follows
185 200 Script output follows
185
186
186 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
187 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
187 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
188 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
188 <head>
189 <head>
189 <link rel="icon" href="/static/hgicon.png" type="image/png" />
190 <link rel="icon" href="/static/hgicon.png" type="image/png" />
190 <meta name="robots" content="index, nofollow" />
191 <meta name="robots" content="index, nofollow" />
191 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
192 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
192 <script type="text/javascript" src="/static/mercurial.js"></script>
193 <script type="text/javascript" src="/static/mercurial.js"></script>
193
194
194 <title>test: log</title>
195 <title>test: log</title>
195 <link rel="alternate" type="application/atom+xml"
196 <link rel="alternate" type="application/atom+xml"
196 href="/atom-log" title="Atom feed for test" />
197 href="/atom-log" title="Atom feed for test" />
197 <link rel="alternate" type="application/rss+xml"
198 <link rel="alternate" type="application/rss+xml"
198 href="/rss-log" title="RSS feed for test" />
199 href="/rss-log" title="RSS feed for test" />
199 </head>
200 </head>
200 <body>
201 <body>
201
202
202 <div class="container">
203 <div class="container">
203 <div class="menu">
204 <div class="menu">
204 <div class="logo">
205 <div class="logo">
205 <a href="http://mercurial.selenic.com/">
206 <a href="http://mercurial.selenic.com/">
206 <img src="/static/hglogo.png" alt="mercurial" /></a>
207 <img src="/static/hglogo.png" alt="mercurial" /></a>
207 </div>
208 </div>
208 <ul>
209 <ul>
209 <li class="active">log</li>
210 <li class="active">log</li>
210 <li><a href="/graph/1d22e65f027e">graph</a></li>
211 <li><a href="/graph/1d22e65f027e">graph</a></li>
211 <li><a href="/tags">tags</a></li>
212 <li><a href="/tags">tags</a></li>
212 <li><a href="/bookmarks">bookmarks</a></li>
213 <li><a href="/bookmarks">bookmarks</a></li>
213 <li><a href="/branches">branches</a></li>
214 <li><a href="/branches">branches</a></li>
214 </ul>
215 </ul>
215 <ul>
216 <ul>
216 <li><a href="/rev/1d22e65f027e">changeset</a></li>
217 <li><a href="/rev/1d22e65f027e">changeset</a></li>
217 <li><a href="/file/1d22e65f027e">browse</a></li>
218 <li><a href="/file/1d22e65f027e">browse</a></li>
218 </ul>
219 </ul>
219 <ul>
220 <ul>
220
221
221 </ul>
222 </ul>
222 <ul>
223 <ul>
223 <li><a href="/help">help</a></li>
224 <li><a href="/help">help</a></li>
224 </ul>
225 </ul>
225 </div>
226 </div>
226
227
227 <div class="main">
228 <div class="main">
228 <h2><a href="/">test</a></h2>
229 <h2><a href="/">test</a></h2>
229 <h3>log</h3>
230 <h3>log</h3>
230
231
231 <form class="search" action="/log">
232 <form class="search" action="/log">
232
233
233 <p><input name="rev" id="search1" type="text" size="30" /></p>
234 <p><input name="rev" id="search1" type="text" size="30" /></p>
234 <div id="hint">find changesets by author, revision,
235 <div id="hint">find changesets by author, revision,
235 files, or words in the commit message</div>
236 files, or words in the commit message</div>
236 </form>
237 </form>
237
238
238 <div class="navigate">
239 <div class="navigate">
239 <a href="/shortlog/2?revcount=30">less</a>
240 <a href="/shortlog/2?revcount=30">less</a>
240 <a href="/shortlog/2?revcount=120">more</a>
241 <a href="/shortlog/2?revcount=120">more</a>
241 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
242 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
242 </div>
243 </div>
243
244
244 <table class="bigtable">
245 <table class="bigtable">
245 <tr>
246 <tr>
246 <th class="age">age</th>
247 <th class="age">age</th>
247 <th class="author">author</th>
248 <th class="author">author</th>
248 <th class="description">description</th>
249 <th class="description">description</th>
249 </tr>
250 </tr>
250 <tr class="parity0">
251 <tr class="parity0">
251 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
252 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
252 <td class="author">test</td>
253 <td class="author">test</td>
253 <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> <span class="tag">something</span> </td>
254 <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> <span class="tag">something</span> </td>
254 </tr>
255 </tr>
255 <tr class="parity1">
256 <tr class="parity1">
256 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
257 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
257 <td class="author">test</td>
258 <td class="author">test</td>
258 <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td>
259 <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td>
259 </tr>
260 </tr>
260 <tr class="parity0">
261 <tr class="parity0">
261 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
262 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
262 <td class="author">test</td>
263 <td class="author">test</td>
263 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
264 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
264 </tr>
265 </tr>
265
266
266 </table>
267 </table>
267
268
268 <div class="navigate">
269 <div class="navigate">
269 <a href="/shortlog/2?revcount=30">less</a>
270 <a href="/shortlog/2?revcount=30">less</a>
270 <a href="/shortlog/2?revcount=120">more</a>
271 <a href="/shortlog/2?revcount=120">more</a>
271 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
272 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
272 </div>
273 </div>
273
274
274 </div>
275 </div>
275 </div>
276 </div>
276
277
277 <script type="text/javascript">process_dates()</script>
278 <script type="text/javascript">process_dates()</script>
278
279
279
280
280 </body>
281 </body>
281 </html>
282 </html>
282
283
283 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/'
284 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/'
284 200 Script output follows
285 200 Script output follows
285
286
286 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
287 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
287 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
288 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
288 <head>
289 <head>
289 <link rel="icon" href="/static/hgicon.png" type="image/png" />
290 <link rel="icon" href="/static/hgicon.png" type="image/png" />
290 <meta name="robots" content="index, nofollow" />
291 <meta name="robots" content="index, nofollow" />
291 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
292 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
292 <script type="text/javascript" src="/static/mercurial.js"></script>
293 <script type="text/javascript" src="/static/mercurial.js"></script>
293
294
294 <title>test: 2ef0ac749a14</title>
295 <title>test: 2ef0ac749a14</title>
295 </head>
296 </head>
296 <body>
297 <body>
297 <div class="container">
298 <div class="container">
298 <div class="menu">
299 <div class="menu">
299 <div class="logo">
300 <div class="logo">
300 <a href="http://mercurial.selenic.com/">
301 <a href="http://mercurial.selenic.com/">
301 <img src="/static/hglogo.png" alt="mercurial" /></a>
302 <img src="/static/hglogo.png" alt="mercurial" /></a>
302 </div>
303 </div>
303 <ul>
304 <ul>
304 <li><a href="/shortlog/2ef0ac749a14">log</a></li>
305 <li><a href="/shortlog/2ef0ac749a14">log</a></li>
305 <li><a href="/graph/2ef0ac749a14">graph</a></li>
306 <li><a href="/graph/2ef0ac749a14">graph</a></li>
306 <li><a href="/tags">tags</a></li>
307 <li><a href="/tags">tags</a></li>
307 <li><a href="/bookmarks">bookmarks</a></li>
308 <li><a href="/bookmarks">bookmarks</a></li>
308 <li><a href="/branches">branches</a></li>
309 <li><a href="/branches">branches</a></li>
309 </ul>
310 </ul>
310 <ul>
311 <ul>
311 <li class="active">changeset</li>
312 <li class="active">changeset</li>
312 <li><a href="/raw-rev/2ef0ac749a14">raw</a></li>
313 <li><a href="/raw-rev/2ef0ac749a14">raw</a></li>
313 <li><a href="/file/2ef0ac749a14">browse</a></li>
314 <li><a href="/file/2ef0ac749a14">browse</a></li>
314 </ul>
315 </ul>
315 <ul>
316 <ul>
316
317
317 </ul>
318 </ul>
318 <ul>
319 <ul>
319 <li><a href="/help">help</a></li>
320 <li><a href="/help">help</a></li>
320 </ul>
321 </ul>
321 </div>
322 </div>
322
323
323 <div class="main">
324 <div class="main">
324
325
325 <h2><a href="/">test</a></h2>
326 <h2><a href="/">test</a></h2>
326 <h3>changeset 0:2ef0ac749a14 <span class="tag">1.0</span> <span class="tag">anotherthing</span> </h3>
327 <h3>changeset 0:2ef0ac749a14 <span class="tag">1.0</span> <span class="tag">anotherthing</span> </h3>
327
328
328 <form class="search" action="/log">
329 <form class="search" action="/log">
329
330
330 <p><input name="rev" id="search1" type="text" size="30" /></p>
331 <p><input name="rev" id="search1" type="text" size="30" /></p>
331 <div id="hint">find changesets by author, revision,
332 <div id="hint">find changesets by author, revision,
332 files, or words in the commit message</div>
333 files, or words in the commit message</div>
333 </form>
334 </form>
334
335
335 <div class="description">base</div>
336 <div class="description">base</div>
336
337
337 <table id="changesetEntry">
338 <table id="changesetEntry">
338 <tr>
339 <tr>
339 <th class="author">author</th>
340 <th class="author">author</th>
340 <td class="author">&#116;&#101;&#115;&#116;</td>
341 <td class="author">&#116;&#101;&#115;&#116;</td>
341 </tr>
342 </tr>
342 <tr>
343 <tr>
343 <th class="date">date</th>
344 <th class="date">date</th>
344 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
345 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
345 <tr>
346 <tr>
346 <th class="author">parents</th>
347 <th class="author">parents</th>
347 <td class="author"></td>
348 <td class="author"></td>
348 </tr>
349 </tr>
349 <tr>
350 <tr>
350 <th class="author">children</th>
351 <th class="author">children</th>
351 <td class="author"> <a href="/rev/a4f92ed23982">a4f92ed23982</a></td>
352 <td class="author"> <a href="/rev/a4f92ed23982">a4f92ed23982</a></td>
352 </tr>
353 </tr>
353 <tr>
354 <tr>
354 <th class="files">files</th>
355 <th class="files">files</th>
355 <td class="files"><a href="/file/2ef0ac749a14/da/foo">da/foo</a> <a href="/file/2ef0ac749a14/foo">foo</a> </td>
356 <td class="files"><a href="/file/2ef0ac749a14/da/foo">da/foo</a> <a href="/file/2ef0ac749a14/foo">foo</a> </td>
356 </tr>
357 </tr>
357 <tr>
358 <tr>
358 <th class="diffstat">diffstat</th>
359 <th class="diffstat">diffstat</th>
359 <td class="diffstat">
360 <td class="diffstat">
360 2 files changed, 2 insertions(+), 0 deletions(-)
361 2 files changed, 2 insertions(+), 0 deletions(-)
361
362
362 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
363 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
363 <div id="diffstatdetails" style="display:none;">
364 <div id="diffstatdetails" style="display:none;">
364 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
365 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
365 <p>
366 <p>
366 <table> <tr class="parity0">
367 <table> <tr class="parity0">
367 <td class="diffstat-file"><a href="#l1.1">da/foo</a></td>
368 <td class="diffstat-file"><a href="#l1.1">da/foo</a></td>
368 <td class="diffstat-total" align="right">1</td>
369 <td class="diffstat-total" align="right">1</td>
369 <td class="diffstat-graph">
370 <td class="diffstat-graph">
370 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
371 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
371 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
372 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
372 </td>
373 </td>
373 </tr>
374 </tr>
374 <tr class="parity1">
375 <tr class="parity1">
375 <td class="diffstat-file"><a href="#l2.1">foo</a></td>
376 <td class="diffstat-file"><a href="#l2.1">foo</a></td>
376 <td class="diffstat-total" align="right">1</td>
377 <td class="diffstat-total" align="right">1</td>
377 <td class="diffstat-graph">
378 <td class="diffstat-graph">
378 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
379 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
379 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
380 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
380 </td>
381 </td>
381 </tr>
382 </tr>
382 </table>
383 </table>
383 </div>
384 </div>
384 </td>
385 </td>
385 </tr>
386 </tr>
386 </table>
387 </table>
387
388
388 <div class="overflow">
389 <div class="overflow">
389 <div class="sourcefirst"> line diff</div>
390 <div class="sourcefirst"> line diff</div>
390
391
391 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
392 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
392 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/da/foo Thu Jan 01 00:00:00 1970 +0000
393 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/da/foo Thu Jan 01 00:00:00 1970 +0000
393 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
394 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
394 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+foo
395 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+foo
395 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
396 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
396 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/foo Thu Jan 01 00:00:00 1970 +0000
397 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/foo Thu Jan 01 00:00:00 1970 +0000
397 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
398 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
398 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+foo
399 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+foo
399 </span></pre></div>
400 </span></pre></div>
400 </div>
401 </div>
401
402
402 </div>
403 </div>
403 </div>
404 </div>
404 <script type="text/javascript">process_dates()</script>
405 <script type="text/javascript">process_dates()</script>
405
406
406
407
407 </body>
408 </body>
408 </html>
409 </html>
409
410
410 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw'
411 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw'
411 200 Script output follows
412 200 Script output follows
412
413
413
414
414 # HG changeset patch
415 # HG changeset patch
415 # User test
416 # User test
416 # Date 0 0
417 # Date 0 0
417 # Node ID a4f92ed23982be056b9852de5dfe873eaac7f0de
418 # Node ID a4f92ed23982be056b9852de5dfe873eaac7f0de
418 # Parent 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
419 # Parent 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
419 Added tag 1.0 for changeset 2ef0ac749a14
420 Added tag 1.0 for changeset 2ef0ac749a14
420
421
421 diff -r 2ef0ac749a14 -r a4f92ed23982 .hgtags
422 diff -r 2ef0ac749a14 -r a4f92ed23982 .hgtags
422 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
423 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
423 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
424 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
424 @@ -0,0 +1,1 @@
425 @@ -0,0 +1,1 @@
425 +2ef0ac749a14e4f57a5a822464a0902c6f7f448f 1.0
426 +2ef0ac749a14e4f57a5a822464a0902c6f7f448f 1.0
426
427
427 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base'
428 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base'
428 200 Script output follows
429 200 Script output follows
429
430
430 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
431 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
431 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
432 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
432 <head>
433 <head>
433 <link rel="icon" href="/static/hgicon.png" type="image/png" />
434 <link rel="icon" href="/static/hgicon.png" type="image/png" />
434 <meta name="robots" content="index, nofollow" />
435 <meta name="robots" content="index, nofollow" />
435 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
436 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
436 <script type="text/javascript" src="/static/mercurial.js"></script>
437 <script type="text/javascript" src="/static/mercurial.js"></script>
437
438
438 <title>test: searching for base</title>
439 <title>test: searching for base</title>
439 </head>
440 </head>
440 <body>
441 <body>
441
442
442 <div class="container">
443 <div class="container">
443 <div class="menu">
444 <div class="menu">
444 <div class="logo">
445 <div class="logo">
445 <a href="http://mercurial.selenic.com/">
446 <a href="http://mercurial.selenic.com/">
446 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
447 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
447 </div>
448 </div>
448 <ul>
449 <ul>
449 <li><a href="/shortlog">log</a></li>
450 <li><a href="/shortlog">log</a></li>
450 <li><a href="/graph">graph</a></li>
451 <li><a href="/graph">graph</a></li>
451 <li><a href="/tags">tags</a></li>
452 <li><a href="/tags">tags</a></li>
452 <li><a href="/bookmarks">bookmarks</a></li>
453 <li><a href="/bookmarks">bookmarks</a></li>
453 <li><a href="/branches">branches</a></li>
454 <li><a href="/branches">branches</a></li>
454 <li><a href="/help">help</a></li>
455 <li><a href="/help">help</a></li>
455 </ul>
456 </ul>
456 </div>
457 </div>
457
458
458 <div class="main">
459 <div class="main">
459 <h2><a href="/">test</a></h2>
460 <h2><a href="/">test</a></h2>
460 <h3>searching for 'base'</h3>
461 <h3>searching for 'base'</h3>
461
462
462 <form class="search" action="/log">
463 <form class="search" action="/log">
463
464
464 <p><input name="rev" id="search1" type="text" size="30"></p>
465 <p><input name="rev" id="search1" type="text" size="30"></p>
465 <div id="hint">find changesets by author, revision,
466 <div id="hint">find changesets by author, revision,
466 files, or words in the commit message</div>
467 files, or words in the commit message</div>
467 </form>
468 </form>
468
469
469 <div class="navigate">
470 <div class="navigate">
470 <a href="/search/?rev=base&revcount=5">less</a>
471 <a href="/search/?rev=base&revcount=5">less</a>
471 <a href="/search/?rev=base&revcount=20">more</a>
472 <a href="/search/?rev=base&revcount=20">more</a>
472 </div>
473 </div>
473
474
474 <table class="bigtable">
475 <table class="bigtable">
475 <tr>
476 <tr>
476 <th class="age">age</th>
477 <th class="age">age</th>
477 <th class="author">author</th>
478 <th class="author">author</th>
478 <th class="description">description</th>
479 <th class="description">description</th>
479 </tr>
480 </tr>
480 <tr class="parity0">
481 <tr class="parity0">
481 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
482 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
482 <td class="author">test</td>
483 <td class="author">test</td>
483 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
484 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
484 </tr>
485 </tr>
485
486
486 </table>
487 </table>
487
488
488 <div class="navigate">
489 <div class="navigate">
489 <a href="/search/?rev=base&revcount=5">less</a>
490 <a href="/search/?rev=base&revcount=5">less</a>
490 <a href="/search/?rev=base&revcount=20">more</a>
491 <a href="/search/?rev=base&revcount=20">more</a>
491 </div>
492 </div>
492
493
493 </div>
494 </div>
494 </div>
495 </div>
495
496
496 <script type="text/javascript">process_dates()</script>
497 <script type="text/javascript">process_dates()</script>
497
498
498
499
499 </body>
500 </body>
500 </html>
501 </html>
501
502
502
503
503 File-related
504 File-related
504
505
505 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw'
506 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw'
506 200 Script output follows
507 200 Script output follows
507
508
508 foo
509 foo
509 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw'
510 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw'
510 200 Script output follows
511 200 Script output follows
511
512
512
513
513 test@0: foo
514 test@0: foo
514
515
515
516
516
517
517
518
518 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw'
519 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw'
519 200 Script output follows
520 200 Script output follows
520
521
521
522
522 drwxr-xr-x da
523 drwxr-xr-x da
523 -rw-r--r-- 45 .hgtags
524 -rw-r--r-- 45 .hgtags
524 -rw-r--r-- 4 foo
525 -rw-r--r-- 4 foo
525
526
526
527
527 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo'
528 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo'
528 200 Script output follows
529 200 Script output follows
529
530
530 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
531 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
531 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
532 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
532 <head>
533 <head>
533 <link rel="icon" href="/static/hgicon.png" type="image/png" />
534 <link rel="icon" href="/static/hgicon.png" type="image/png" />
534 <meta name="robots" content="index, nofollow" />
535 <meta name="robots" content="index, nofollow" />
535 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
536 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
536 <script type="text/javascript" src="/static/mercurial.js"></script>
537 <script type="text/javascript" src="/static/mercurial.js"></script>
537
538
538 <title>test: a4f92ed23982 foo</title>
539 <title>test: a4f92ed23982 foo</title>
539 </head>
540 </head>
540 <body>
541 <body>
541
542
542 <div class="container">
543 <div class="container">
543 <div class="menu">
544 <div class="menu">
544 <div class="logo">
545 <div class="logo">
545 <a href="http://mercurial.selenic.com/">
546 <a href="http://mercurial.selenic.com/">
546 <img src="/static/hglogo.png" alt="mercurial" /></a>
547 <img src="/static/hglogo.png" alt="mercurial" /></a>
547 </div>
548 </div>
548 <ul>
549 <ul>
549 <li><a href="/shortlog/a4f92ed23982">log</a></li>
550 <li><a href="/shortlog/a4f92ed23982">log</a></li>
550 <li><a href="/graph/a4f92ed23982">graph</a></li>
551 <li><a href="/graph/a4f92ed23982">graph</a></li>
551 <li><a href="/tags">tags</a></li>
552 <li><a href="/tags">tags</a></li>
552 <li><a href="/branches">branches</a></li>
553 <li><a href="/branches">branches</a></li>
553 </ul>
554 </ul>
554 <ul>
555 <ul>
555 <li><a href="/rev/a4f92ed23982">changeset</a></li>
556 <li><a href="/rev/a4f92ed23982">changeset</a></li>
556 <li><a href="/file/a4f92ed23982/">browse</a></li>
557 <li><a href="/file/a4f92ed23982/">browse</a></li>
557 </ul>
558 </ul>
558 <ul>
559 <ul>
559 <li class="active">file</li>
560 <li class="active">file</li>
560 <li><a href="/file/tip/foo">latest</a></li>
561 <li><a href="/file/tip/foo">latest</a></li>
561 <li><a href="/diff/a4f92ed23982/foo">diff</a></li>
562 <li><a href="/diff/a4f92ed23982/foo">diff</a></li>
562 <li><a href="/annotate/a4f92ed23982/foo">annotate</a></li>
563 <li><a href="/annotate/a4f92ed23982/foo">annotate</a></li>
563 <li><a href="/log/a4f92ed23982/foo">file log</a></li>
564 <li><a href="/log/a4f92ed23982/foo">file log</a></li>
564 <li><a href="/raw-file/a4f92ed23982/foo">raw</a></li>
565 <li><a href="/raw-file/a4f92ed23982/foo">raw</a></li>
565 </ul>
566 </ul>
566 <ul>
567 <ul>
567 <li><a href="/help">help</a></li>
568 <li><a href="/help">help</a></li>
568 </ul>
569 </ul>
569 </div>
570 </div>
570
571
571 <div class="main">
572 <div class="main">
572 <h2><a href="/">test</a></h2>
573 <h2><a href="/">test</a></h2>
573 <h3>view foo @ 1:a4f92ed23982</h3>
574 <h3>view foo @ 1:a4f92ed23982</h3>
574
575
575 <form class="search" action="/log">
576 <form class="search" action="/log">
576
577
577 <p><input name="rev" id="search1" type="text" size="30" /></p>
578 <p><input name="rev" id="search1" type="text" size="30" /></p>
578 <div id="hint">find changesets by author, revision,
579 <div id="hint">find changesets by author, revision,
579 files, or words in the commit message</div>
580 files, or words in the commit message</div>
580 </form>
581 </form>
581
582
582 <div class="description">Added tag 1.0 for changeset 2ef0ac749a14</div>
583 <div class="description">Added tag 1.0 for changeset 2ef0ac749a14</div>
583
584
584 <table id="changesetEntry">
585 <table id="changesetEntry">
585 <tr>
586 <tr>
586 <th class="author">author</th>
587 <th class="author">author</th>
587 <td class="author">&#116;&#101;&#115;&#116;</td>
588 <td class="author">&#116;&#101;&#115;&#116;</td>
588 </tr>
589 </tr>
589 <tr>
590 <tr>
590 <th class="date">date</th>
591 <th class="date">date</th>
591 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
592 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
592 </tr>
593 </tr>
593 <tr>
594 <tr>
594 <th class="author">parents</th>
595 <th class="author">parents</th>
595 <td class="author"></td>
596 <td class="author"></td>
596 </tr>
597 </tr>
597 <tr>
598 <tr>
598 <th class="author">children</th>
599 <th class="author">children</th>
599 <td class="author"><a href="/file/1d22e65f027e/foo">1d22e65f027e</a> </td>
600 <td class="author"><a href="/file/1d22e65f027e/foo">1d22e65f027e</a> </td>
600 </tr>
601 </tr>
601
602
602 </table>
603 </table>
603
604
604 <div class="overflow">
605 <div class="overflow">
605 <div class="sourcefirst"> line source</div>
606 <div class="sourcefirst"> line source</div>
606
607
607 <div class="parity0 source"><a href="#l1" id="l1"> 1</a> foo
608 <div class="parity0 source"><a href="#l1" id="l1"> 1</a> foo
608 </div>
609 </div>
609 <div class="sourcelast"></div>
610 <div class="sourcelast"></div>
610 </div>
611 </div>
611 </div>
612 </div>
612 </div>
613 </div>
613
614
614 <script type="text/javascript">process_dates()</script>
615 <script type="text/javascript">process_dates()</script>
615
616
616
617
617 </body>
618 </body>
618 </html>
619 </html>
619
620
620 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw'
621 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw'
621 200 Script output follows
622 200 Script output follows
622
623
623
624
624 diff -r 000000000000 -r a4f92ed23982 foo
625 diff -r 000000000000 -r a4f92ed23982 foo
625 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
626 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
626 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
627 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
627 @@ -0,0 +1,1 @@
628 @@ -0,0 +1,1 @@
628 +foo
629 +foo
629
630
630
631
631
632
632
633
633
634
634 Overviews
635 Overviews
635
636
636 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags'
637 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags'
637 200 Script output follows
638 200 Script output follows
638
639
639 tip 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
640 tip 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
640 1.0 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
641 1.0 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
641 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches'
642 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches'
642 200 Script output follows
643 200 Script output follows
643
644
644 stable 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe open
645 stable 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe open
645 default a4f92ed23982be056b9852de5dfe873eaac7f0de inactive
646 default a4f92ed23982be056b9852de5dfe873eaac7f0de inactive
646 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-bookmarks'
647 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-bookmarks'
647 200 Script output follows
648 200 Script output follows
648
649
649 anotherthing 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
650 anotherthing 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
650 something 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
651 something 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
651 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
652 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
652 200 Script output follows
653 200 Script output follows
653
654
654 <?xml version="1.0" encoding="ascii"?>
655 <?xml version="1.0" encoding="ascii"?>
655 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
656 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
656 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
657 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
657 <head>
658 <head>
658 <link rel="icon" href="/static/hgicon.png" type="image/png" />
659 <link rel="icon" href="/static/hgicon.png" type="image/png" />
659 <meta name="robots" content="index, nofollow"/>
660 <meta name="robots" content="index, nofollow"/>
660 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
661 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
661 <script type="text/javascript" src="/static/mercurial.js"></script>
662 <script type="text/javascript" src="/static/mercurial.js"></script>
662
663
663 <title>test: Summary</title>
664 <title>test: Summary</title>
664 <link rel="alternate" type="application/atom+xml"
665 <link rel="alternate" type="application/atom+xml"
665 href="/atom-log" title="Atom feed for test"/>
666 href="/atom-log" title="Atom feed for test"/>
666 <link rel="alternate" type="application/rss+xml"
667 <link rel="alternate" type="application/rss+xml"
667 href="/rss-log" title="RSS feed for test"/>
668 href="/rss-log" title="RSS feed for test"/>
668 </head>
669 </head>
669 <body>
670 <body>
670
671
671 <div class="page_header">
672 <div class="page_header">
672 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / summary
673 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / summary
673
674
674 <form action="/log">
675 <form action="/log">
675 <input type="hidden" name="style" value="gitweb" />
676 <input type="hidden" name="style" value="gitweb" />
676 <div class="search">
677 <div class="search">
677 <input type="text" name="rev" />
678 <input type="text" name="rev" />
678 </div>
679 </div>
679 </form>
680 </form>
680 </div>
681 </div>
681
682
682 <div class="page_nav">
683 <div class="page_nav">
683 summary |
684 summary |
684 <a href="/shortlog?style=gitweb">shortlog</a> |
685 <a href="/shortlog?style=gitweb">shortlog</a> |
685 <a href="/log?style=gitweb">changelog</a> |
686 <a href="/log?style=gitweb">changelog</a> |
686 <a href="/graph?style=gitweb">graph</a> |
687 <a href="/graph?style=gitweb">graph</a> |
687 <a href="/tags?style=gitweb">tags</a> |
688 <a href="/tags?style=gitweb">tags</a> |
688 <a href="/bookmarks?style=gitweb">bookmarks</a> |
689 <a href="/bookmarks?style=gitweb">bookmarks</a> |
689 <a href="/branches?style=gitweb">branches</a> |
690 <a href="/branches?style=gitweb">branches</a> |
690 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
691 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
691 <a href="/help?style=gitweb">help</a>
692 <a href="/help?style=gitweb">help</a>
692 <br/>
693 <br/>
693 </div>
694 </div>
694
695
695 <div class="title">&nbsp;</div>
696 <div class="title">&nbsp;</div>
696 <table cellspacing="0">
697 <table cellspacing="0">
697 <tr><td>description</td><td>unknown</td></tr>
698 <tr><td>description</td><td>unknown</td></tr>
698 <tr><td>owner</td><td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td></tr>
699 <tr><td>owner</td><td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td></tr>
699 <tr><td>last change</td><td>Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
700 <tr><td>last change</td><td>Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
700 </table>
701 </table>
701
702
702 <div><a class="title" href="/shortlog?style=gitweb">changes</a></div>
703 <div><a class="title" href="/shortlog?style=gitweb">changes</a></div>
703 <table cellspacing="0">
704 <table cellspacing="0">
704
705
705 <tr class="parity0">
706 <tr class="parity0">
706 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
707 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
707 <td><i>test</i></td>
708 <td><i>test</i></td>
708 <td>
709 <td>
709 <a class="list" href="/rev/1d22e65f027e?style=gitweb">
710 <a class="list" href="/rev/1d22e65f027e?style=gitweb">
710 <b>branch</b>
711 <b>branch</b>
711 <span class="logtags"><span class="branchtag" title="stable">stable</span> <span class="tagtag" title="tip">tip</span> <span class="bookmarktag" title="something">something</span> </span>
712 <span class="logtags"><span class="branchtag" title="stable">stable</span> <span class="tagtag" title="tip">tip</span> <span class="bookmarktag" title="something">something</span> </span>
712 </a>
713 </a>
713 </td>
714 </td>
714 <td class="link" nowrap>
715 <td class="link" nowrap>
715 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
716 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
716 <a href="/file/1d22e65f027e?style=gitweb">files</a>
717 <a href="/file/1d22e65f027e?style=gitweb">files</a>
717 </td>
718 </td>
718 </tr>
719 </tr>
719 <tr class="parity1">
720 <tr class="parity1">
720 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
721 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
721 <td><i>test</i></td>
722 <td><i>test</i></td>
722 <td>
723 <td>
723 <a class="list" href="/rev/a4f92ed23982?style=gitweb">
724 <a class="list" href="/rev/a4f92ed23982?style=gitweb">
724 <b>Added tag 1.0 for changeset 2ef0ac749a14</b>
725 <b>Added tag 1.0 for changeset 2ef0ac749a14</b>
725 <span class="logtags"><span class="branchtag" title="default">default</span> </span>
726 <span class="logtags"><span class="branchtag" title="default">default</span> </span>
726 </a>
727 </a>
727 </td>
728 </td>
728 <td class="link" nowrap>
729 <td class="link" nowrap>
729 <a href="/rev/a4f92ed23982?style=gitweb">changeset</a> |
730 <a href="/rev/a4f92ed23982?style=gitweb">changeset</a> |
730 <a href="/file/a4f92ed23982?style=gitweb">files</a>
731 <a href="/file/a4f92ed23982?style=gitweb">files</a>
731 </td>
732 </td>
732 </tr>
733 </tr>
733 <tr class="parity0">
734 <tr class="parity0">
734 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
735 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
735 <td><i>test</i></td>
736 <td><i>test</i></td>
736 <td>
737 <td>
737 <a class="list" href="/rev/2ef0ac749a14?style=gitweb">
738 <a class="list" href="/rev/2ef0ac749a14?style=gitweb">
738 <b>base</b>
739 <b>base</b>
739 <span class="logtags"><span class="tagtag" title="1.0">1.0</span> <span class="bookmarktag" title="anotherthing">anotherthing</span> </span>
740 <span class="logtags"><span class="tagtag" title="1.0">1.0</span> <span class="bookmarktag" title="anotherthing">anotherthing</span> </span>
740 </a>
741 </a>
741 </td>
742 </td>
742 <td class="link" nowrap>
743 <td class="link" nowrap>
743 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
744 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
744 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
745 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
745 </td>
746 </td>
746 </tr>
747 </tr>
747 <tr class="light"><td colspan="4"><a class="list" href="/shortlog?style=gitweb">...</a></td></tr>
748 <tr class="light"><td colspan="4"><a class="list" href="/shortlog?style=gitweb">...</a></td></tr>
748 </table>
749 </table>
749
750
750 <div><a class="title" href="/tags?style=gitweb">tags</a></div>
751 <div><a class="title" href="/tags?style=gitweb">tags</a></div>
751 <table cellspacing="0">
752 <table cellspacing="0">
752
753
753 <tr class="parity0">
754 <tr class="parity0">
754 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
755 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
755 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td>
756 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td>
756 <td class="link">
757 <td class="link">
757 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
758 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
758 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
759 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
759 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
760 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
760 </td>
761 </td>
761 </tr>
762 </tr>
762 <tr class="light"><td colspan="3"><a class="list" href="/tags?style=gitweb">...</a></td></tr>
763 <tr class="light"><td colspan="3"><a class="list" href="/tags?style=gitweb">...</a></td></tr>
763 </table>
764 </table>
764
765
765 <div><a class="title" href="/bookmarks?style=gitweb">bookmarks</a></div>
766 <div><a class="title" href="/bookmarks?style=gitweb">bookmarks</a></div>
766 <table cellspacing="0">
767 <table cellspacing="0">
767
768
768 <tr class="parity0">
769 <tr class="parity0">
769 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
770 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
770 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>anotherthing</b></a></td>
771 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>anotherthing</b></a></td>
771 <td class="link">
772 <td class="link">
772 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
773 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
773 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
774 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
774 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
775 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
775 </td>
776 </td>
776 </tr>
777 </tr>
777 <tr class="parity1">
778 <tr class="parity1">
778 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
779 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
779 <td><a class="list" href="/rev/1d22e65f027e?style=gitweb"><b>something</b></a></td>
780 <td><a class="list" href="/rev/1d22e65f027e?style=gitweb"><b>something</b></a></td>
780 <td class="link">
781 <td class="link">
781 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
782 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
782 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
783 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
783 <a href="/file/1d22e65f027e?style=gitweb">files</a>
784 <a href="/file/1d22e65f027e?style=gitweb">files</a>
784 </td>
785 </td>
785 </tr>
786 </tr>
786 <tr class="light"><td colspan="3"><a class="list" href="/bookmarks?style=gitweb">...</a></td></tr>
787 <tr class="light"><td colspan="3"><a class="list" href="/bookmarks?style=gitweb">...</a></td></tr>
787 </table>
788 </table>
788
789
789 <div><a class="title" href="#">branches</a></div>
790 <div><a class="title" href="#">branches</a></div>
790 <table cellspacing="0">
791 <table cellspacing="0">
791
792
792 <tr class="parity0">
793 <tr class="parity0">
793 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
794 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
794 <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
795 <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
795 <td class="">stable</td>
796 <td class="">stable</td>
796 <td class="link">
797 <td class="link">
797 <a href="/changeset/1d22e65f027e?style=gitweb">changeset</a> |
798 <a href="/changeset/1d22e65f027e?style=gitweb">changeset</a> |
798 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
799 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
799 <a href="/file/1d22e65f027e?style=gitweb">files</a>
800 <a href="/file/1d22e65f027e?style=gitweb">files</a>
800 </td>
801 </td>
801 </tr>
802 </tr>
802 <tr class="parity1">
803 <tr class="parity1">
803 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
804 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
804 <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
805 <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
805 <td class="">default</td>
806 <td class="">default</td>
806 <td class="link">
807 <td class="link">
807 <a href="/changeset/a4f92ed23982?style=gitweb">changeset</a> |
808 <a href="/changeset/a4f92ed23982?style=gitweb">changeset</a> |
808 <a href="/log/a4f92ed23982?style=gitweb">changelog</a> |
809 <a href="/log/a4f92ed23982?style=gitweb">changelog</a> |
809 <a href="/file/a4f92ed23982?style=gitweb">files</a>
810 <a href="/file/a4f92ed23982?style=gitweb">files</a>
810 </td>
811 </td>
811 </tr>
812 </tr>
812 <tr class="light">
813 <tr class="light">
813 <td colspan="4"><a class="list" href="#">...</a></td>
814 <td colspan="4"><a class="list" href="#">...</a></td>
814 </tr>
815 </tr>
815 </table>
816 </table>
816 <script type="text/javascript">process_dates()</script>
817 <script type="text/javascript">process_dates()</script>
817 <div class="page_footer">
818 <div class="page_footer">
818 <div class="page_footer_text">test</div>
819 <div class="page_footer_text">test</div>
819 <div class="rss_logo">
820 <div class="rss_logo">
820 <a href="/rss-log">RSS</a>
821 <a href="/rss-log">RSS</a>
821 <a href="/atom-log">Atom</a>
822 <a href="/atom-log">Atom</a>
822 </div>
823 </div>
823 <br />
824 <br />
824
825
825 </div>
826 </div>
826 </body>
827 </body>
827 </html>
828 </html>
828
829
829 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb'
830 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb'
830 200 Script output follows
831 200 Script output follows
831
832
832 <?xml version="1.0" encoding="ascii"?>
833 <?xml version="1.0" encoding="ascii"?>
833 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
834 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
834 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
835 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
835 <head>
836 <head>
836 <link rel="icon" href="/static/hgicon.png" type="image/png" />
837 <link rel="icon" href="/static/hgicon.png" type="image/png" />
837 <meta name="robots" content="index, nofollow"/>
838 <meta name="robots" content="index, nofollow"/>
838 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
839 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
839 <script type="text/javascript" src="/static/mercurial.js"></script>
840 <script type="text/javascript" src="/static/mercurial.js"></script>
840
841
841 <title>test: Graph</title>
842 <title>test: Graph</title>
842 <link rel="alternate" type="application/atom+xml"
843 <link rel="alternate" type="application/atom+xml"
843 href="/atom-log" title="Atom feed for test"/>
844 href="/atom-log" title="Atom feed for test"/>
844 <link rel="alternate" type="application/rss+xml"
845 <link rel="alternate" type="application/rss+xml"
845 href="/rss-log" title="RSS feed for test"/>
846 href="/rss-log" title="RSS feed for test"/>
846 <!--[if IE]><script type="text/javascript" src="/static/excanvas.js"></script><![endif]-->
847 <!--[if IE]><script type="text/javascript" src="/static/excanvas.js"></script><![endif]-->
847 </head>
848 </head>
848 <body>
849 <body>
849
850
850 <div class="page_header">
851 <div class="page_header">
851 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / graph
852 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / graph
852 </div>
853 </div>
853
854
854 <form action="/log">
855 <form action="/log">
855 <input type="hidden" name="style" value="gitweb" />
856 <input type="hidden" name="style" value="gitweb" />
856 <div class="search">
857 <div class="search">
857 <input type="text" name="rev" />
858 <input type="text" name="rev" />
858 </div>
859 </div>
859 </form>
860 </form>
860 <div class="page_nav">
861 <div class="page_nav">
861 <a href="/summary?style=gitweb">summary</a> |
862 <a href="/summary?style=gitweb">summary</a> |
862 <a href="/shortlog?style=gitweb">shortlog</a> |
863 <a href="/shortlog?style=gitweb">shortlog</a> |
863 <a href="/log/2?style=gitweb">changelog</a> |
864 <a href="/log/2?style=gitweb">changelog</a> |
864 graph |
865 graph |
865 <a href="/tags?style=gitweb">tags</a> |
866 <a href="/tags?style=gitweb">tags</a> |
866 <a href="/bookmarks?style=gitweb">bookmarks</a> |
867 <a href="/bookmarks?style=gitweb">bookmarks</a> |
867 <a href="/branches?style=gitweb">branches</a> |
868 <a href="/branches?style=gitweb">branches</a> |
868 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
869 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
869 <a href="/help?style=gitweb">help</a>
870 <a href="/help?style=gitweb">help</a>
870 <br/>
871 <br/>
871 <a href="/graph/2?style=gitweb&revcount=30">less</a>
872 <a href="/graph/2?style=gitweb&revcount=30">less</a>
872 <a href="/graph/2?style=gitweb&revcount=120">more</a>
873 <a href="/graph/2?style=gitweb&revcount=120">more</a>
873 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a> <br/>
874 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a> <br/>
874 </div>
875 </div>
875
876
876 <div class="title">&nbsp;</div>
877 <div class="title">&nbsp;</div>
877
878
878 <noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
879 <noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
879
880
880 <div id="wrapper">
881 <div id="wrapper">
881 <ul id="nodebgs"></ul>
882 <ul id="nodebgs"></ul>
882 <canvas id="graph" width="480" height="129"></canvas>
883 <canvas id="graph" width="480" height="129"></canvas>
883 <ul id="graphnodes"></ul>
884 <ul id="graphnodes"></ul>
884 </div>
885 </div>
885
886
886 <script>
887 <script>
887 <!-- hide script content
888 <!-- hide script content
888
889
889 var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
890 var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
890 var graph = new Graph();
891 var graph = new Graph();
891 graph.scale(39);
892 graph.scale(39);
892
893
893 graph.edge = function(x0, y0, x1, y1, color) {
894 graph.edge = function(x0, y0, x1, y1, color) {
894
895
895 this.setColor(color, 0.0, 0.65);
896 this.setColor(color, 0.0, 0.65);
896 this.ctx.beginPath();
897 this.ctx.beginPath();
897 this.ctx.moveTo(x0, y0);
898 this.ctx.moveTo(x0, y0);
898 this.ctx.lineTo(x1, y1);
899 this.ctx.lineTo(x1, y1);
899 this.ctx.stroke();
900 this.ctx.stroke();
900
901
901 }
902 }
902
903
903 var revlink = '<li style="_STYLE"><span class="desc">';
904 var revlink = '<li style="_STYLE"><span class="desc">';
904 revlink += '<a class="list" href="/rev/_NODEID?style=gitweb" title="_NODEID"><b>_DESC</b></a>';
905 revlink += '<a class="list" href="/rev/_NODEID?style=gitweb" title="_NODEID"><b>_DESC</b></a>';
905 revlink += '</span> _TAGS';
906 revlink += '</span> _TAGS';
906 revlink += '<span class="info">_DATE, by _USER</span></li>';
907 revlink += '<span class="info">_DATE, by _USER</span></li>';
907
908
908 graph.vertex = function(x, y, color, parity, cur) {
909 graph.vertex = function(x, y, color, parity, cur) {
909
910
910 this.ctx.beginPath();
911 this.ctx.beginPath();
911 color = this.setColor(color, 0.25, 0.75);
912 color = this.setColor(color, 0.25, 0.75);
912 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
913 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
913 this.ctx.fill();
914 this.ctx.fill();
914
915
915 var bg = '<li class="bg parity' + parity + '"></li>';
916 var bg = '<li class="bg parity' + parity + '"></li>';
916 var left = (this.columns + 1) * this.bg_height;
917 var left = (this.columns + 1) * this.bg_height;
917 var nstyle = 'padding-left: ' + left + 'px;';
918 var nstyle = 'padding-left: ' + left + 'px;';
918 var item = revlink.replace(/_STYLE/, nstyle);
919 var item = revlink.replace(/_STYLE/, nstyle);
919 item = item.replace(/_PARITY/, 'parity' + parity);
920 item = item.replace(/_PARITY/, 'parity' + parity);
920 item = item.replace(/_NODEID/, cur[0]);
921 item = item.replace(/_NODEID/, cur[0]);
921 item = item.replace(/_NODEID/, cur[0]);
922 item = item.replace(/_NODEID/, cur[0]);
922 item = item.replace(/_DESC/, cur[3]);
923 item = item.replace(/_DESC/, cur[3]);
923 item = item.replace(/_USER/, cur[4]);
924 item = item.replace(/_USER/, cur[4]);
924 item = item.replace(/_DATE/, cur[5]);
925 item = item.replace(/_DATE/, cur[5]);
925
926
926 var tagspan = '';
927 var tagspan = '';
927 if (cur[7].length || cur[8].length || (cur[6][0] != 'default' || cur[6][1])) {
928 if (cur[7].length || cur[8].length || (cur[6][0] != 'default' || cur[6][1])) {
928 tagspan = '<span class="logtags">';
929 tagspan = '<span class="logtags">';
929 if (cur[6][1]) {
930 if (cur[6][1]) {
930 tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
931 tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
931 tagspan += cur[6][0] + '</span> ';
932 tagspan += cur[6][0] + '</span> ';
932 } else if (!cur[6][1] && cur[6][0] != 'default') {
933 } else if (!cur[6][1] && cur[6][0] != 'default') {
933 tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
934 tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
934 tagspan += cur[6][0] + '</span> ';
935 tagspan += cur[6][0] + '</span> ';
935 }
936 }
936 if (cur[7].length) {
937 if (cur[7].length) {
937 for (var t in cur[7]) {
938 for (var t in cur[7]) {
938 var tag = cur[7][t];
939 var tag = cur[7][t];
939 tagspan += '<span class="tagtag">' + tag + '</span> ';
940 tagspan += '<span class="tagtag">' + tag + '</span> ';
940 }
941 }
941 }
942 }
942 if (cur[8].length) {
943 if (cur[8].length) {
943 for (var t in cur[8]) {
944 for (var t in cur[8]) {
944 var bookmark = cur[8][t];
945 var bookmark = cur[8][t];
945 tagspan += '<span class="bookmarktag">' + bookmark + '</span> ';
946 tagspan += '<span class="bookmarktag">' + bookmark + '</span> ';
946 }
947 }
947 }
948 }
948 tagspan += '</span>';
949 tagspan += '</span>';
949 }
950 }
950
951
951 item = item.replace(/_TAGS/, tagspan);
952 item = item.replace(/_TAGS/, tagspan);
952 return [bg, item];
953 return [bg, item];
953
954
954 }
955 }
955
956
956 graph.render(data);
957 graph.render(data);
957
958
958 // stop hiding script -->
959 // stop hiding script -->
959 </script>
960 </script>
960
961
961 <div class="page_nav">
962 <div class="page_nav">
962 <a href="/graph/2?style=gitweb&revcount=30">less</a>
963 <a href="/graph/2?style=gitweb&revcount=30">less</a>
963 <a href="/graph/2?style=gitweb&revcount=120">more</a>
964 <a href="/graph/2?style=gitweb&revcount=120">more</a>
964 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a>
965 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a>
965 </div>
966 </div>
966
967
967 <script type="text/javascript">process_dates()</script>
968 <script type="text/javascript">process_dates()</script>
968 <div class="page_footer">
969 <div class="page_footer">
969 <div class="page_footer_text">test</div>
970 <div class="page_footer_text">test</div>
970 <div class="rss_logo">
971 <div class="rss_logo">
971 <a href="/rss-log">RSS</a>
972 <a href="/rss-log">RSS</a>
972 <a href="/atom-log">Atom</a>
973 <a href="/atom-log">Atom</a>
973 </div>
974 </div>
974 <br />
975 <br />
975
976
976 </div>
977 </div>
977 </body>
978 </body>
978 </html>
979 </html>
979
980
980
981
981 capabilities
982 capabilities
982
983
983 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
984 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
984 200 Script output follows
985 200 Script output follows
985
986
986 lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
987 lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
987
988
988 heads
989 heads
989
990
990 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads'
991 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads'
991 200 Script output follows
992 200 Script output follows
992
993
993 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
994 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
994
995
995 branches
996 branches
996
997
997 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches&nodes=0000000000000000000000000000000000000000'
998 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches&nodes=0000000000000000000000000000000000000000'
998 200 Script output follows
999 200 Script output follows
999
1000
1000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
1001 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
1001
1002
1002 changegroup
1003 changegroup
1003
1004
1004 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup&roots=0000000000000000000000000000000000000000'
1005 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup&roots=0000000000000000000000000000000000000000'
1005 200 Script output follows
1006 200 Script output follows
1006
1007
1007 x\x9c\xbdTMHUA\x14\xbe\xa8\xf9\xec\xda&\x10\x11*\xb8\x88\x81\x99\xbef\xe6\xce\xbdw\xc6\xf2a\x16E\x1b\x11[%\x98\xcc\xaf\x8f\x8c\xf7\xc0\xf7\x82 (esc)
1008 x\x9c\xbdTMHUA\x14\xbe\xa8\xf9\xec\xda&\x10\x11*\xb8\x88\x81\x99\xbef\xe6\xce\xbdw\xc6\xf2a\x16E\x1b\x11[%\x98\xcc\xaf\x8f\x8c\xf7\xc0\xf7\x82 (esc)
1008 4\x11KP2m\x95\xad*\xabE\x05AP\xd0\xc22Z\x14\xf9\x03\xb9j\xa3\x9b$\xa4MJ\xb4\x90\xc0\x9a\x9bO0\x10\xdf\x13\xa2\x81\x0f\x869g\xe6|\xe7\x9c\xef\x8ceY\xf7\xa2KO\xd2\xb7K\x16~\\n\xe9\xad\x90w\x86\xab\x93W\x8e\xdf\xb0r\\Y\xee6(\xa2)\xf6\x95\xc6\x01\xe4\x1az\x80R\xe8kN\x98\xe7R\xa4\xa9K@\xe0!A\xb4k\xa7U*m\x03\x07\xd8\x92\x1d\xd2\xc9\xa4\x1d\xc2\xe6,\xa5\xcc+\x1f\xef\xafDgi\xef\xab\x1d\x1d\xb7\x9a\xe7[W\xfbc\x8f\xde-\xcd\xe7\xcaz\xb3\xbb\x19\xd3\x81\x10>c>\x08\x00"X\x11\xc2\x84@\xd2\xe7B*L\x00\x01P\x04R\xc3@\xbaB0\xdb8#\x83:\x83\xa2h\xbc=\xcd\xdaS\xe1Y,L\xd3\xa0\xf2\xa8\x94J:\xe6\xd8\x81Q\xe0\xe8d\xa7#\xe2,\xd1\xaeR*\xed \xa5\x01\x13\x01\xa6\x0cb\xe3;\xbe\xaf\xfcK[^wK\xe1N\xaf\xbbk\xe8B\xd1\xf4\xc1\x07\xb3\xab[\x10\xfdkmvwcB\xa6\xa4\xd4G\xc4D\xc2\x141\xad\x91\x10\x00\x08J\x81\xcb}\xee \xee+W\xba\x8a\x80\x90|\xd4\xa0\xd6\xa0\xd4T\xde\xe1\x9d,!\xe2\xb5\xa94\xe3\xe7\xd5\x9f\x06\x18\xcba\x03aP\xb8f\xcd\x04\x1a_\\9\xf1\xed\xe4\x9e\xe5\xa6\xd1\xd2\x9f\x03\xa7o\xae\x90H\xf3\xfb\xef\xffH3\xadk (esc)
1009 4\x11KP2m\x95\xad*\xabE\x05AP\xd0\xc22Z\x14\xf9\x03\xb9j\xa3\x9b$\xa4MJ\xb4\x90\xc0\x9a\x9bO0\x10\xdf\x13\xa2\x81\x0f\x869g\xe6|\xe7\x9c\xef\x8ceY\xf7\xa2KO\xd2\xb7K\x16~\\n\xe9\xad\x90w\x86\xab\x93W\x8e\xdf\xb0r\\Y\xee6(\xa2)\xf6\x95\xc6\x01\xe4\x1az\x80R\xe8kN\x98\xe7R\xa4\xa9K@\xe0!A\xb4k\xa7U*m\x03\x07\xd8\x92\x1d\xd2\xc9\xa4\x1d\xc2\xe6,\xa5\xcc+\x1f\xef\xafDgi\xef\xab\x1d\x1d\xb7\x9a\xe7[W\xfbc\x8f\xde-\xcd\xe7\xcaz\xb3\xbb\x19\xd3\x81\x10>c>\x08\x00"X\x11\xc2\x84@\xd2\xe7B*L\x00\x01P\x04R\xc3@\xbaB0\xdb8#\x83:\x83\xa2h\xbc=\xcd\xdaS\xe1Y,L\xd3\xa0\xf2\xa8\x94J:\xe6\xd8\x81Q\xe0\xe8d\xa7#\xe2,\xd1\xaeR*\xed \xa5\x01\x13\x01\xa6\x0cb\xe3;\xbe\xaf\xfcK[^wK\xe1N\xaf\xbbk\xe8B\xd1\xf4\xc1\x07\xb3\xab[\x10\xfdkmvwcB\xa6\xa4\xd4G\xc4D\xc2\x141\xad\x91\x10\x00\x08J\x81\xcb}\xee \xee+W\xba\x8a\x80\x90|\xd4\xa0\xd6\xa0\xd4T\xde\xe1\x9d,!\xe2\xb5\xa94\xe3\xe7\xd5\x9f\x06\x18\xcba\x03aP\xb8f\xcd\x04\x1a_\\9\xf1\xed\xe4\x9e\xe5\xa6\xd1\xd2\x9f\x03\xa7o\xae\x90H\xf3\xfb\xef\xffH3\xadk (esc)
1009 \xb0\x90\x92\x88\xb9\x14"\x068\xc2\x1e@\x00\xbb\x8a)\xd3'\x859 (esc)
1010 \xb0\x90\x92\x88\xb9\x14"\x068\xc2\x1e@\x00\xbb\x8a)\xd3'\x859 (esc)
1010 \xa8\x80\x84S \xa5\xbd-g\x13`\xe4\xdc\xc3H^\xdf\xe2\xc0TM\xc7\xf4BO\xcf\xde\xae\xe5\xae#\x1frM(K\x97`F\x19\x16s\x05GD\xb9\x01\xc1\x00+\x8c|\x9fp\xc11\xf0\x14\x00\x9cJ\x82<\xe0\x12\x9f\xc1\x90\xd0\xf5\xc8\x19>Pr\xaa\xeaW\xf5\xc4\xae\xd1\xfc\x17\xcf'\x13u\xb1\x9e\xcdHnC\x0e\xcc`\xc8\xa0&\xac\x0e\xf1|\x8c\x10$\xc4\x8c\xa2p\x05`\xdc\x08 \x80\xc4\xd7Rr-\x94\x10\x102\xedi;\xf3f\xf1z\x16\x86\xdb\xd8d\xe5\xe7\x8b\xf5\x8d\rzp\xb2\xfe\xac\xf5\xf2\xd3\xfe\xfckws\xedt\x96b\xd5l\x1c\x0b\x85\xb5\x170\x8f\x11\x84\xb0\x8f\x19\xa0\x00 _\x07\x1ac\xa2\xc3\x89Z\xe7\x96\xf9 \xccNFg\xc7F\xaa\x8a+\x9a\x9cc_\x17\x1b\x17\x9e]z38<\x97+\xb5,",\xc8\xc8?\\\x91\xff\x17.~U\x96\x97\xf5%\xdeN<\x8e\xf5\x97%\xe7^\xcfL\xed~\xda\x96k\xdc->\x86\x02\x83"\x96H\xa6\xe3\xaas=-\xeb7\xe5\xda\x8f\xbc (no-eol) (esc)
1011 \xa8\x80\x84S \xa5\xbd-g\x13`\xe4\xdc\xc3H^\xdf\xe2\xc0TM\xc7\xf4BO\xcf\xde\xae\xe5\xae#\x1frM(K\x97`F\x19\x16s\x05GD\xb9\x01\xc1\x00+\x8c|\x9fp\xc11\xf0\x14\x00\x9cJ\x82<\xe0\x12\x9f\xc1\x90\xd0\xf5\xc8\x19>Pr\xaa\xeaW\xf5\xc4\xae\xd1\xfc\x17\xcf'\x13u\xb1\x9e\xcdHnC\x0e\xcc`\xc8\xa0&\xac\x0e\xf1|\x8c\x10$\xc4\x8c\xa2p\x05`\xdc\x08 \x80\xc4\xd7Rr-\x94\x10\x102\xedi;\xf3f\xf1z\x16\x86\xdb\xd8d\xe5\xe7\x8b\xf5\x8d\rzp\xb2\xfe\xac\xf5\xf2\xd3\xfe\xfckws\xedt\x96b\xd5l\x1c\x0b\x85\xb5\x170\x8f\x11\x84\xb0\x8f\x19\xa0\x00 _\x07\x1ac\xa2\xc3\x89Z\xe7\x96\xf9 \xccNFg\xc7F\xaa\x8a+\x9a\x9cc_\x17\x1b\x17\x9e]z38<\x97+\xb5,",\xc8\xc8?\\\x91\xff\x17.~U\x96\x97\xf5%\xdeN<\x8e\xf5\x97%\xe7^\xcfL\xed~\xda\x96k\xdc->\x86\x02\x83"\x96H\xa6\xe3\xaas=-\xeb7\xe5\xda\x8f\xbc (no-eol) (esc)
1011
1012
1012 stream_out
1013 stream_out
1013
1014
1014 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'
1015 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'
1015 200 Script output follows
1016 200 Script output follows
1016
1017
1017 1
1018 1
1018
1019
1019 failing unbundle, requires POST request
1020 failing unbundle, requires POST request
1020
1021
1021 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle'
1022 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle'
1022 405 push requires POST request
1023 405 push requires POST request
1023
1024
1024 0
1025 0
1025 push requires POST request
1026 push requires POST request
1026 [1]
1027 [1]
1027
1028
1028 Static files
1029 Static files
1029
1030
1030 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
1031 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
1031 200 Script output follows
1032 200 Script output follows
1032
1033
1033 a { text-decoration:none; }
1034 a { text-decoration:none; }
1034 .age { white-space:nowrap; }
1035 .age { white-space:nowrap; }
1035 .date { white-space:nowrap; }
1036 .date { white-space:nowrap; }
1036 .indexlinks { white-space:nowrap; }
1037 .indexlinks { white-space:nowrap; }
1037 .parity0 { background-color: #ddd; }
1038 .parity0 { background-color: #ddd; }
1038 .parity1 { background-color: #eee; }
1039 .parity1 { background-color: #eee; }
1039 .lineno { width: 60px; color: #aaa; font-size: smaller;
1040 .lineno { width: 60px; color: #aaa; font-size: smaller;
1040 text-align: right; }
1041 text-align: right; }
1041 .plusline { color: green; }
1042 .plusline { color: green; }
1042 .minusline { color: red; }
1043 .minusline { color: red; }
1043 .atline { color: purple; }
1044 .atline { color: purple; }
1044 .annotate { font-size: smaller; text-align: right; padding-right: 1em; }
1045 .annotate { font-size: smaller; text-align: right; padding-right: 1em; }
1045 .buttons a {
1046 .buttons a {
1046 background-color: #666;
1047 background-color: #666;
1047 padding: 2pt;
1048 padding: 2pt;
1048 color: white;
1049 color: white;
1049 font-family: sans;
1050 font-family: sans;
1050 font-weight: bold;
1051 font-weight: bold;
1051 }
1052 }
1052 .navigate a {
1053 .navigate a {
1053 background-color: #ccc;
1054 background-color: #ccc;
1054 padding: 2pt;
1055 padding: 2pt;
1055 font-family: sans;
1056 font-family: sans;
1056 color: black;
1057 color: black;
1057 }
1058 }
1058
1059
1059 .metatag {
1060 .metatag {
1060 background-color: #888;
1061 background-color: #888;
1061 color: white;
1062 color: white;
1062 text-align: right;
1063 text-align: right;
1063 }
1064 }
1064
1065
1065 /* Common */
1066 /* Common */
1066 pre { margin: 0; }
1067 pre { margin: 0; }
1067
1068
1068 .logo {
1069 .logo {
1069 float: right;
1070 float: right;
1070 clear: right;
1071 clear: right;
1071 }
1072 }
1072
1073
1073 /* Changelog/Filelog entries */
1074 /* Changelog/Filelog entries */
1074 .logEntry { width: 100%; }
1075 .logEntry { width: 100%; }
1075 .logEntry .age { width: 15%; }
1076 .logEntry .age { width: 15%; }
1076 .logEntry th { font-weight: normal; text-align: right; vertical-align: top; }
1077 .logEntry th { font-weight: normal; text-align: right; vertical-align: top; }
1077 .logEntry th.age, .logEntry th.firstline { font-weight: bold; }
1078 .logEntry th.age, .logEntry th.firstline { font-weight: bold; }
1078 .logEntry th.firstline { text-align: left; width: inherit; }
1079 .logEntry th.firstline { text-align: left; width: inherit; }
1079
1080
1080 /* Shortlog entries */
1081 /* Shortlog entries */
1081 .slogEntry { width: 100%; }
1082 .slogEntry { width: 100%; }
1082 .slogEntry .age { width: 8em; }
1083 .slogEntry .age { width: 8em; }
1083 .slogEntry td { font-weight: normal; text-align: left; vertical-align: top; }
1084 .slogEntry td { font-weight: normal; text-align: left; vertical-align: top; }
1084 .slogEntry td.author { width: 15em; }
1085 .slogEntry td.author { width: 15em; }
1085
1086
1086 /* Tag entries */
1087 /* Tag entries */
1087 #tagEntries { list-style: none; margin: 0; padding: 0; }
1088 #tagEntries { list-style: none; margin: 0; padding: 0; }
1088 #tagEntries .tagEntry { list-style: none; margin: 0; padding: 0; }
1089 #tagEntries .tagEntry { list-style: none; margin: 0; padding: 0; }
1089
1090
1090 /* Changeset entry */
1091 /* Changeset entry */
1091 #changesetEntry { }
1092 #changesetEntry { }
1092 #changesetEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1093 #changesetEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1093 #changesetEntry th.files, #changesetEntry th.description { vertical-align: top; }
1094 #changesetEntry th.files, #changesetEntry th.description { vertical-align: top; }
1094
1095
1095 /* File diff view */
1096 /* File diff view */
1096 #filediffEntry { }
1097 #filediffEntry { }
1097 #filediffEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1098 #filediffEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1098
1099
1099 /* Graph */
1100 /* Graph */
1100 div#wrapper {
1101 div#wrapper {
1101 position: relative;
1102 position: relative;
1102 margin: 0;
1103 margin: 0;
1103 padding: 0;
1104 padding: 0;
1104 }
1105 }
1105
1106
1106 canvas {
1107 canvas {
1107 position: absolute;
1108 position: absolute;
1108 z-index: 5;
1109 z-index: 5;
1109 top: -0.6em;
1110 top: -0.6em;
1110 margin: 0;
1111 margin: 0;
1111 }
1112 }
1112
1113
1113 ul#nodebgs {
1114 ul#nodebgs {
1114 list-style: none inside none;
1115 list-style: none inside none;
1115 padding: 0;
1116 padding: 0;
1116 margin: 0;
1117 margin: 0;
1117 top: -0.7em;
1118 top: -0.7em;
1118 }
1119 }
1119
1120
1120 ul#graphnodes li, ul#nodebgs li {
1121 ul#graphnodes li, ul#nodebgs li {
1121 height: 39px;
1122 height: 39px;
1122 }
1123 }
1123
1124
1124 ul#graphnodes {
1125 ul#graphnodes {
1125 position: absolute;
1126 position: absolute;
1126 z-index: 10;
1127 z-index: 10;
1127 top: -0.85em;
1128 top: -0.85em;
1128 list-style: none inside none;
1129 list-style: none inside none;
1129 padding: 0;
1130 padding: 0;
1130 }
1131 }
1131
1132
1132 ul#graphnodes li .info {
1133 ul#graphnodes li .info {
1133 display: block;
1134 display: block;
1134 font-size: 70%;
1135 font-size: 70%;
1135 position: relative;
1136 position: relative;
1136 top: -1px;
1137 top: -1px;
1137 }
1138 }
1138
1139
1139 Stop and restart with HGENCODING=cp932
1140 Stop and restart with HGENCODING=cp932
1140
1141
1141 $ "$TESTDIR/killdaemons.py"
1142 $ "$TESTDIR/killdaemons.py"
1142 $ HGENCODING=cp932 hg serve --config server.uncompressed=False -n test \
1143 $ HGENCODING=cp932 hg serve --config server.uncompressed=False -n test \
1143 > -p $HGPORT -d --pid-file=hg.pid -E errors.log
1144 > -p $HGPORT -d --pid-file=hg.pid -E errors.log
1144 $ cat hg.pid >> $DAEMON_PIDS
1145 $ cat hg.pid >> $DAEMON_PIDS
1145
1146
1146 commit message with Japanese Kanji 'Noh', which ends with '\x5c'
1147 commit message with Japanese Kanji 'Noh', which ends with '\x5c'
1147
1148
1148 $ echo foo >> foo
1149 $ echo foo >> foo
1149 $ HGENCODING=cp932 hg ci -m `python -c 'print("\x94\x5c")'`
1150 $ HGENCODING=cp932 hg ci -m `python -c 'print("\x94\x5c")'`
1150
1151
1151 Graph json escape of multibyte character
1152 Graph json escape of multibyte character
1152
1153
1153 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/' \
1154 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/' \
1154 > | grep '^var data ='
1155 > | grep '^var data ='
1155 var data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
1156 var data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
1156
1157
1157 ERRORS ENCOUNTERED
1158 ERRORS ENCOUNTERED
1158
1159
1159 $ cat errors.log
1160 $ cat errors.log
@@ -1,93 +1,94 b''
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 $ hgserve() {
3 $ hgserve() {
4 > hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -E errors.log -v $@
4 > hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -E errors.log -v $@
5 > cat hg.pid >> "$DAEMON_PIDS"
5 > cat hg.pid >> "$DAEMON_PIDS"
6 > }
6 > }
7 $ hg init a
7 $ hg init a
8 $ hg --encoding utf-8 -R a branch æ
8 $ hg --encoding utf-8 -R a branch æ
9 marked working directory as branch \xc3\xa6 (esc)
9 marked working directory as branch \xc3\xa6 (esc)
10 (branches are permanent and global, did you want a bookmark?)
10 $ echo foo > a/foo
11 $ echo foo > a/foo
11 $ hg -R a ci -Am foo
12 $ hg -R a ci -Am foo
12 adding foo
13 adding foo
13 $ hgserve -R a --config web.push_ssl=False --config web.allow_push=* --encoding latin1
14 $ hgserve -R a --config web.push_ssl=False --config web.allow_push=* --encoding latin1
14 listening at http://*:$HGPORT1/ (bound to 127.0.0.1:$HGPORT1) (glob)
15 listening at http://*:$HGPORT1/ (bound to 127.0.0.1:$HGPORT1) (glob)
15 $ hg --encoding utf-8 clone http://localhost:$HGPORT1 b
16 $ hg --encoding utf-8 clone http://localhost:$HGPORT1 b
16 requesting all changes
17 requesting all changes
17 adding changesets
18 adding changesets
18 adding manifests
19 adding manifests
19 adding file changes
20 adding file changes
20 added 1 changesets with 1 changes to 1 files
21 added 1 changesets with 1 changes to 1 files
21 updating to branch \xc3\xa6 (esc)
22 updating to branch \xc3\xa6 (esc)
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 $ hg --encoding utf-8 -R b log
24 $ hg --encoding utf-8 -R b log
24 changeset: 0:867c11ce77b8
25 changeset: 0:867c11ce77b8
25 branch: \xc3\xa6 (esc)
26 branch: \xc3\xa6 (esc)
26 tag: tip
27 tag: tip
27 user: test
28 user: test
28 date: Thu Jan 01 00:00:00 1970 +0000
29 date: Thu Jan 01 00:00:00 1970 +0000
29 summary: foo
30 summary: foo
30
31
31 $ echo bar >> b/foo
32 $ echo bar >> b/foo
32 $ hg -R b ci -m bar
33 $ hg -R b ci -m bar
33 $ hg --encoding utf-8 -R b push
34 $ hg --encoding utf-8 -R b push
34 pushing to http://localhost:$HGPORT1/
35 pushing to http://localhost:$HGPORT1/
35 searching for changes
36 searching for changes
36 remote: adding changesets
37 remote: adding changesets
37 remote: adding manifests
38 remote: adding manifests
38 remote: adding file changes
39 remote: adding file changes
39 remote: added 1 changesets with 1 changes to 1 files
40 remote: added 1 changesets with 1 changes to 1 files
40 $ hg -R a --encoding utf-8 log
41 $ hg -R a --encoding utf-8 log
41 changeset: 1:58e7c90d67cb
42 changeset: 1:58e7c90d67cb
42 branch: \xc3\xa6 (esc)
43 branch: \xc3\xa6 (esc)
43 tag: tip
44 tag: tip
44 user: test
45 user: test
45 date: Thu Jan 01 00:00:00 1970 +0000
46 date: Thu Jan 01 00:00:00 1970 +0000
46 summary: bar
47 summary: bar
47
48
48 changeset: 0:867c11ce77b8
49 changeset: 0:867c11ce77b8
49 branch: \xc3\xa6 (esc)
50 branch: \xc3\xa6 (esc)
50 user: test
51 user: test
51 date: Thu Jan 01 00:00:00 1970 +0000
52 date: Thu Jan 01 00:00:00 1970 +0000
52 summary: foo
53 summary: foo
53
54
54 $ kill `cat hg.pid`
55 $ kill `cat hg.pid`
55
56
56 verify 7e7d56fe4833 (encoding fallback in branchmap to maintain compatibility with 1.3.x)
57 verify 7e7d56fe4833 (encoding fallback in branchmap to maintain compatibility with 1.3.x)
57
58
58 $ cat <<EOF > oldhg
59 $ cat <<EOF > oldhg
59 > import sys
60 > import sys
60 > from mercurial import ui, hg, commands
61 > from mercurial import ui, hg, commands
61 >
62 >
62 > class StdoutWrapper(object):
63 > class StdoutWrapper(object):
63 > def __init__(self, stdout):
64 > def __init__(self, stdout):
64 > self._file = stdout
65 > self._file = stdout
65 >
66 >
66 > def write(self, data):
67 > def write(self, data):
67 > if data == '47\n':
68 > if data == '47\n':
68 > # latin1 encoding is one %xx (3 bytes) shorter
69 > # latin1 encoding is one %xx (3 bytes) shorter
69 > data = '44\n'
70 > data = '44\n'
70 > elif data.startswith('%C3%A6 '):
71 > elif data.startswith('%C3%A6 '):
71 > # translate to latin1 encoding
72 > # translate to latin1 encoding
72 > data = '%%E6 %s' % data[7:]
73 > data = '%%E6 %s' % data[7:]
73 > self._file.write(data)
74 > self._file.write(data)
74 >
75 >
75 > def __getattr__(self, name):
76 > def __getattr__(self, name):
76 > return getattr(self._file, name)
77 > return getattr(self._file, name)
77 >
78 >
78 > sys.stdout = StdoutWrapper(sys.stdout)
79 > sys.stdout = StdoutWrapper(sys.stdout)
79 > sys.stderr = StdoutWrapper(sys.stderr)
80 > sys.stderr = StdoutWrapper(sys.stderr)
80 >
81 >
81 > myui = ui.ui()
82 > myui = ui.ui()
82 > repo = hg.repository(myui, 'a')
83 > repo = hg.repository(myui, 'a')
83 > commands.serve(myui, repo, stdio=True, cmdserver=False)
84 > commands.serve(myui, repo, stdio=True, cmdserver=False)
84 > EOF
85 > EOF
85 $ echo baz >> b/foo
86 $ echo baz >> b/foo
86 $ hg -R b ci -m baz
87 $ hg -R b ci -m baz
87 $ hg push -R b -e 'python oldhg' ssh://dummy/ --encoding latin1
88 $ hg push -R b -e 'python oldhg' ssh://dummy/ --encoding latin1
88 pushing to ssh://dummy/
89 pushing to ssh://dummy/
89 searching for changes
90 searching for changes
90 remote: adding changesets
91 remote: adding changesets
91 remote: adding manifests
92 remote: adding manifests
92 remote: adding file changes
93 remote: adding file changes
93 remote: added 1 changesets with 1 changes to 1 files
94 remote: added 1 changesets with 1 changes to 1 files
@@ -1,56 +1,57 b''
1 $ cat >findbranch.py <<EOF
1 $ cat >findbranch.py <<EOF
2 > import re, sys
2 > import re, sys
3 >
3 >
4 > head_re = re.compile('^#(?:(?:\\s+([A-Za-z][A-Za-z0-9_]*)(?:\\s.*)?)|(?:\\s*))$')
4 > head_re = re.compile('^#(?:(?:\\s+([A-Za-z][A-Za-z0-9_]*)(?:\\s.*)?)|(?:\\s*))$')
5 >
5 >
6 > for line in sys.stdin:
6 > for line in sys.stdin:
7 > hmatch = head_re.match(line)
7 > hmatch = head_re.match(line)
8 > if not hmatch:
8 > if not hmatch:
9 > sys.exit(1)
9 > sys.exit(1)
10 > if hmatch.group(1) == 'Branch':
10 > if hmatch.group(1) == 'Branch':
11 > sys.exit(0)
11 > sys.exit(0)
12 > sys.exit(1)
12 > sys.exit(1)
13 > EOF
13 > EOF
14
14
15 $ hg init a
15 $ hg init a
16 $ cd a
16 $ cd a
17 $ echo "Rev 1" >rev
17 $ echo "Rev 1" >rev
18 $ hg add rev
18 $ hg add rev
19 $ hg commit -m "No branch."
19 $ hg commit -m "No branch."
20 $ hg branch abranch
20 $ hg branch abranch
21 marked working directory as branch abranch
21 marked working directory as branch abranch
22 (branches are permanent and global, did you want a bookmark?)
22 $ echo "Rev 2" >rev
23 $ echo "Rev 2" >rev
23 $ hg commit -m "With branch."
24 $ hg commit -m "With branch."
24
25
25 $ hg export 0 > ../r0.patch
26 $ hg export 0 > ../r0.patch
26 $ hg export 1 > ../r1.patch
27 $ hg export 1 > ../r1.patch
27 $ cd ..
28 $ cd ..
28
29
29 $ if python findbranch.py < r0.patch; then
30 $ if python findbranch.py < r0.patch; then
30 > echo "Export of default branch revision has Branch header" 1>&2
31 > echo "Export of default branch revision has Branch header" 1>&2
31 > exit 1
32 > exit 1
32 > fi
33 > fi
33
34
34 $ if python findbranch.py < r1.patch; then
35 $ if python findbranch.py < r1.patch; then
35 > : # Do nothing
36 > : # Do nothing
36 > else
37 > else
37 > echo "Export of branch revision is missing Branch header" 1>&2
38 > echo "Export of branch revision is missing Branch header" 1>&2
38 > exit 1
39 > exit 1
39 > fi
40 > fi
40
41
41 Make sure import still works with branch information in patches.
42 Make sure import still works with branch information in patches.
42
43
43 $ hg init b
44 $ hg init b
44 $ cd b
45 $ cd b
45 $ hg import ../r0.patch
46 $ hg import ../r0.patch
46 applying ../r0.patch
47 applying ../r0.patch
47 $ hg import ../r1.patch
48 $ hg import ../r1.patch
48 applying ../r1.patch
49 applying ../r1.patch
49 $ cd ..
50 $ cd ..
50
51
51 $ hg init c
52 $ hg init c
52 $ cd c
53 $ cd c
53 $ hg import --exact ../r0.patch
54 $ hg import --exact ../r0.patch
54 applying ../r0.patch
55 applying ../r0.patch
55 $ hg import --exact ../r1.patch
56 $ hg import --exact ../r1.patch
56 applying ../r1.patch
57 applying ../r1.patch
@@ -1,258 +1,259 b''
1 $ "$TESTDIR/hghave" symlink execbit || exit 80
1 $ "$TESTDIR/hghave" symlink execbit || exit 80
2
2
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "purge=" >> $HGRCPATH
4 $ echo "purge=" >> $HGRCPATH
5 $ echo "graphlog=" >> $HGRCPATH
5 $ echo "graphlog=" >> $HGRCPATH
6
6
7 $ shortlog() {
7 $ shortlog() {
8 > hg glog --template '{rev}:{node|short} {author} {date|hgdate} - {branch} - {desc|firstline}\n'
8 > hg glog --template '{rev}:{node|short} {author} {date|hgdate} - {branch} - {desc|firstline}\n'
9 > }
9 > }
10
10
11 Test --bypass with other options
11 Test --bypass with other options
12
12
13 $ hg init repo-options
13 $ hg init repo-options
14 $ cd repo-options
14 $ cd repo-options
15 $ echo a > a
15 $ echo a > a
16 $ hg ci -Am adda
16 $ hg ci -Am adda
17 adding a
17 adding a
18 $ echo a >> a
18 $ echo a >> a
19 $ hg branch foo
19 $ hg branch foo
20 marked working directory as branch foo
20 marked working directory as branch foo
21 (branches are permanent and global, did you want a bookmark?)
21 $ hg ci -Am changea
22 $ hg ci -Am changea
22 $ hg export . > ../test.diff
23 $ hg export . > ../test.diff
23 $ hg up null
24 $ hg up null
24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
25 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
25
26
26 Test importing an existing revision
27 Test importing an existing revision
27
28
28 $ hg import --bypass --exact ../test.diff
29 $ hg import --bypass --exact ../test.diff
29 applying ../test.diff
30 applying ../test.diff
30 $ shortlog
31 $ shortlog
31 o 1:4e322f7ce8e3 test 0 0 - foo - changea
32 o 1:4e322f7ce8e3 test 0 0 - foo - changea
32 |
33 |
33 o 0:07f494440405 test 0 0 - default - adda
34 o 0:07f494440405 test 0 0 - default - adda
34
35
35
36
36 Test failure without --exact
37 Test failure without --exact
37
38
38 $ hg import --bypass ../test.diff
39 $ hg import --bypass ../test.diff
39 applying ../test.diff
40 applying ../test.diff
40 unable to find 'a' for patching
41 unable to find 'a' for patching
41 abort: patch failed to apply
42 abort: patch failed to apply
42 [255]
43 [255]
43 $ hg st
44 $ hg st
44 $ shortlog
45 $ shortlog
45 o 1:4e322f7ce8e3 test 0 0 - foo - changea
46 o 1:4e322f7ce8e3 test 0 0 - foo - changea
46 |
47 |
47 o 0:07f494440405 test 0 0 - default - adda
48 o 0:07f494440405 test 0 0 - default - adda
48
49
49
50
50 Test --user, --date and --message
51 Test --user, --date and --message
51
52
52 $ hg up 0
53 $ hg up 0
53 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 $ hg import --bypass --u test2 -d '1 0' -m patch2 ../test.diff
55 $ hg import --bypass --u test2 -d '1 0' -m patch2 ../test.diff
55 applying ../test.diff
56 applying ../test.diff
56 $ cat .hg/last-message.txt
57 $ cat .hg/last-message.txt
57 patch2 (no-eol)
58 patch2 (no-eol)
58 $ shortlog
59 $ shortlog
59 o 2:2e127d1da504 test2 1 0 - default - patch2
60 o 2:2e127d1da504 test2 1 0 - default - patch2
60 |
61 |
61 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
62 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
62 |/
63 |/
63 @ 0:07f494440405 test 0 0 - default - adda
64 @ 0:07f494440405 test 0 0 - default - adda
64
65
65 $ hg rollback
66 $ hg rollback
66 repository tip rolled back to revision 1 (undo import)
67 repository tip rolled back to revision 1 (undo import)
67
68
68 Test --import-branch
69 Test --import-branch
69
70
70 $ hg import --bypass --import-branch ../test.diff
71 $ hg import --bypass --import-branch ../test.diff
71 applying ../test.diff
72 applying ../test.diff
72 $ shortlog
73 $ shortlog
73 o 1:4e322f7ce8e3 test 0 0 - foo - changea
74 o 1:4e322f7ce8e3 test 0 0 - foo - changea
74 |
75 |
75 @ 0:07f494440405 test 0 0 - default - adda
76 @ 0:07f494440405 test 0 0 - default - adda
76
77
77 $ hg rollback
78 $ hg rollback
78 repository tip rolled back to revision 1 (undo import)
79 repository tip rolled back to revision 1 (undo import)
79
80
80 Test --strip
81 Test --strip
81
82
82 $ hg import --bypass --strip 0 - <<EOF
83 $ hg import --bypass --strip 0 - <<EOF
83 > # HG changeset patch
84 > # HG changeset patch
84 > # User test
85 > # User test
85 > # Date 0 0
86 > # Date 0 0
86 > # Branch foo
87 > # Branch foo
87 > # Node ID 4e322f7ce8e3e4203950eac9ece27bf7e45ffa6c
88 > # Node ID 4e322f7ce8e3e4203950eac9ece27bf7e45ffa6c
88 > # Parent 07f4944404050f47db2e5c5071e0e84e7a27bba9
89 > # Parent 07f4944404050f47db2e5c5071e0e84e7a27bba9
89 > changea
90 > changea
90 >
91 >
91 > diff -r 07f494440405 -r 4e322f7ce8e3 a
92 > diff -r 07f494440405 -r 4e322f7ce8e3 a
92 > --- a Thu Jan 01 00:00:00 1970 +0000
93 > --- a Thu Jan 01 00:00:00 1970 +0000
93 > +++ a Thu Jan 01 00:00:00 1970 +0000
94 > +++ a Thu Jan 01 00:00:00 1970 +0000
94 > @@ -1,1 +1,2 @@
95 > @@ -1,1 +1,2 @@
95 > a
96 > a
96 > +a
97 > +a
97 > EOF
98 > EOF
98 applying patch from stdin
99 applying patch from stdin
99 $ hg rollback
100 $ hg rollback
100 repository tip rolled back to revision 1 (undo import)
101 repository tip rolled back to revision 1 (undo import)
101
102
102 Test unsupported combinations
103 Test unsupported combinations
103
104
104 $ hg import --bypass --no-commit ../test.diff
105 $ hg import --bypass --no-commit ../test.diff
105 abort: cannot use --no-commit with --bypass
106 abort: cannot use --no-commit with --bypass
106 [255]
107 [255]
107 $ hg import --bypass --similarity 50 ../test.diff
108 $ hg import --bypass --similarity 50 ../test.diff
108 abort: cannot use --similarity with --bypass
109 abort: cannot use --similarity with --bypass
109 [255]
110 [255]
110
111
111 Test commit editor
112 Test commit editor
112
113
113 $ hg diff -c 1 > ../test.diff
114 $ hg diff -c 1 > ../test.diff
114 $ HGEDITOR=cat hg import --bypass ../test.diff
115 $ HGEDITOR=cat hg import --bypass ../test.diff
115 applying ../test.diff
116 applying ../test.diff
116
117
117
118
118 HG: Enter commit message. Lines beginning with 'HG:' are removed.
119 HG: Enter commit message. Lines beginning with 'HG:' are removed.
119 HG: Leave message empty to abort commit.
120 HG: Leave message empty to abort commit.
120 HG: --
121 HG: --
121 HG: user: test
122 HG: user: test
122 HG: branch 'default'
123 HG: branch 'default'
123 HG: changed a
124 HG: changed a
124 abort: empty commit message
125 abort: empty commit message
125 [255]
126 [255]
126
127
127 Test patch.eol is handled
128 Test patch.eol is handled
128
129
129 $ python -c 'file("a", "wb").write("a\r\n")'
130 $ python -c 'file("a", "wb").write("a\r\n")'
130 $ hg ci -m makeacrlf
131 $ hg ci -m makeacrlf
131 $ hg import -m 'should fail because of eol' --bypass ../test.diff
132 $ hg import -m 'should fail because of eol' --bypass ../test.diff
132 applying ../test.diff
133 applying ../test.diff
133 patching file a
134 patching file a
134 Hunk #1 FAILED at 0
135 Hunk #1 FAILED at 0
135 abort: patch failed to apply
136 abort: patch failed to apply
136 [255]
137 [255]
137 $ hg --config patch.eol=auto import -d '0 0' -m 'test patch.eol' --bypass ../test.diff
138 $ hg --config patch.eol=auto import -d '0 0' -m 'test patch.eol' --bypass ../test.diff
138 applying ../test.diff
139 applying ../test.diff
139 $ shortlog
140 $ shortlog
140 o 3:d7805b4d2cb3 test 0 0 - default - test patch.eol
141 o 3:d7805b4d2cb3 test 0 0 - default - test patch.eol
141 |
142 |
142 @ 2:872023de769d test 0 0 - default - makeacrlf
143 @ 2:872023de769d test 0 0 - default - makeacrlf
143 |
144 |
144 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
145 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
145 |/
146 |/
146 o 0:07f494440405 test 0 0 - default - adda
147 o 0:07f494440405 test 0 0 - default - adda
147
148
148
149
149 Test applying multiple patches
150 Test applying multiple patches
150
151
151 $ hg up -qC 0
152 $ hg up -qC 0
152 $ echo e > e
153 $ echo e > e
153 $ hg ci -Am adde
154 $ hg ci -Am adde
154 adding e
155 adding e
155 created new head
156 created new head
156 $ hg export . > ../patch1.diff
157 $ hg export . > ../patch1.diff
157 $ hg up -qC 1
158 $ hg up -qC 1
158 $ echo f > f
159 $ echo f > f
159 $ hg ci -Am addf
160 $ hg ci -Am addf
160 adding f
161 adding f
161 $ hg export . > ../patch2.diff
162 $ hg export . > ../patch2.diff
162 $ cd ..
163 $ cd ..
163 $ hg clone -r1 repo-options repo-multi1
164 $ hg clone -r1 repo-options repo-multi1
164 adding changesets
165 adding changesets
165 adding manifests
166 adding manifests
166 adding file changes
167 adding file changes
167 added 2 changesets with 2 changes to 1 files
168 added 2 changesets with 2 changes to 1 files
168 updating to branch foo
169 updating to branch foo
169 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
170 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
170 $ cd repo-multi1
171 $ cd repo-multi1
171 $ hg up 0
172 $ hg up 0
172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 $ hg import --bypass ../patch1.diff ../patch2.diff
174 $ hg import --bypass ../patch1.diff ../patch2.diff
174 applying ../patch1.diff
175 applying ../patch1.diff
175 applying ../patch2.diff
176 applying ../patch2.diff
176 $ shortlog
177 $ shortlog
177 o 3:bc8ca3f8a7c4 test 0 0 - default - addf
178 o 3:bc8ca3f8a7c4 test 0 0 - default - addf
178 |
179 |
179 o 2:16581080145e test 0 0 - default - adde
180 o 2:16581080145e test 0 0 - default - adde
180 |
181 |
181 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
182 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
182 |/
183 |/
183 @ 0:07f494440405 test 0 0 - default - adda
184 @ 0:07f494440405 test 0 0 - default - adda
184
185
185
186
186 Test applying multiple patches with --exact
187 Test applying multiple patches with --exact
187
188
188 $ cd ..
189 $ cd ..
189 $ hg clone -r1 repo-options repo-multi2
190 $ hg clone -r1 repo-options repo-multi2
190 adding changesets
191 adding changesets
191 adding manifests
192 adding manifests
192 adding file changes
193 adding file changes
193 added 2 changesets with 2 changes to 1 files
194 added 2 changesets with 2 changes to 1 files
194 updating to branch foo
195 updating to branch foo
195 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 $ cd repo-multi2
197 $ cd repo-multi2
197 $ hg import --bypass --exact ../patch1.diff ../patch2.diff
198 $ hg import --bypass --exact ../patch1.diff ../patch2.diff
198 applying ../patch1.diff
199 applying ../patch1.diff
199 applying ../patch2.diff
200 applying ../patch2.diff
200 $ shortlog
201 $ shortlog
201 o 3:d60cb8989666 test 0 0 - foo - addf
202 o 3:d60cb8989666 test 0 0 - foo - addf
202 |
203 |
203 | o 2:16581080145e test 0 0 - default - adde
204 | o 2:16581080145e test 0 0 - default - adde
204 | |
205 | |
205 @ | 1:4e322f7ce8e3 test 0 0 - foo - changea
206 @ | 1:4e322f7ce8e3 test 0 0 - foo - changea
206 |/
207 |/
207 o 0:07f494440405 test 0 0 - default - adda
208 o 0:07f494440405 test 0 0 - default - adda
208
209
209
210
210 $ cd ..
211 $ cd ..
211
212
212 Test complicated patch with --exact
213 Test complicated patch with --exact
213
214
214 $ hg init repo-exact
215 $ hg init repo-exact
215 $ cd repo-exact
216 $ cd repo-exact
216 $ echo a > a
217 $ echo a > a
217 $ echo c > c
218 $ echo c > c
218 $ echo d > d
219 $ echo d > d
219 $ echo e > e
220 $ echo e > e
220 $ echo f > f
221 $ echo f > f
221 $ chmod +x f
222 $ chmod +x f
222 $ ln -s c linkc
223 $ ln -s c linkc
223 $ hg ci -Am t
224 $ hg ci -Am t
224 adding a
225 adding a
225 adding c
226 adding c
226 adding d
227 adding d
227 adding e
228 adding e
228 adding f
229 adding f
229 adding linkc
230 adding linkc
230 $ hg cp a aa1
231 $ hg cp a aa1
231 $ echo b >> a
232 $ echo b >> a
232 $ echo b > b
233 $ echo b > b
233 $ hg add b
234 $ hg add b
234 $ hg cp a aa2
235 $ hg cp a aa2
235 $ echo aa >> aa2
236 $ echo aa >> aa2
236 $ chmod +x e
237 $ chmod +x e
237 $ chmod -x f
238 $ chmod -x f
238 $ ln -s a linka
239 $ ln -s a linka
239 $ hg rm d
240 $ hg rm d
240 $ hg rm linkc
241 $ hg rm linkc
241 $ hg mv c cc
242 $ hg mv c cc
242 $ hg ci -m patch
243 $ hg ci -m patch
243 $ hg export --git . > ../test.diff
244 $ hg export --git . > ../test.diff
244 $ hg up -C null
245 $ hg up -C null
245 0 files updated, 0 files merged, 7 files removed, 0 files unresolved
246 0 files updated, 0 files merged, 7 files removed, 0 files unresolved
246 $ hg purge
247 $ hg purge
247 $ hg st
248 $ hg st
248 $ hg import --bypass --exact ../test.diff
249 $ hg import --bypass --exact ../test.diff
249 applying ../test.diff
250 applying ../test.diff
250
251
251 The patch should have matched the exported revision and generated no additional
252 The patch should have matched the exported revision and generated no additional
252 data. If not, diff both heads to debug it.
253 data. If not, diff both heads to debug it.
253
254
254 $ shortlog
255 $ shortlog
255 o 1:2978fd5c8aa4 test 0 0 - default - patch
256 o 1:2978fd5c8aa4 test 0 0 - default - patch
256 |
257 |
257 o 0:a0e19e636a43 test 0 0 - default - t
258 o 0:a0e19e636a43 test 0 0 - default - t
258
259
@@ -1,95 +1,96 b''
1 http://mercurial.selenic.com/bts/issue1306
1 http://mercurial.selenic.com/bts/issue1306
2
2
3 Initialize remote repo with branches:
3 Initialize remote repo with branches:
4
4
5 $ hg init remote
5 $ hg init remote
6 $ cd remote
6 $ cd remote
7
7
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -Ama
9 $ hg ci -Ama
10 adding a
10 adding a
11
11
12 $ hg branch br
12 $ hg branch br
13 marked working directory as branch br
13 marked working directory as branch br
14 (branches are permanent and global, did you want a bookmark?)
14 $ hg ci -Amb
15 $ hg ci -Amb
15
16
16 $ echo c > c
17 $ echo c > c
17 $ hg ci -Amc
18 $ hg ci -Amc
18 adding c
19 adding c
19
20
20 $ hg log
21 $ hg log
21 changeset: 2:ae3d9c30ec50
22 changeset: 2:ae3d9c30ec50
22 branch: br
23 branch: br
23 tag: tip
24 tag: tip
24 user: test
25 user: test
25 date: Thu Jan 01 00:00:00 1970 +0000
26 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: c
27 summary: c
27
28
28 changeset: 1:3f7f930ca414
29 changeset: 1:3f7f930ca414
29 branch: br
30 branch: br
30 user: test
31 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
32 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: b
33 summary: b
33
34
34 changeset: 0:cb9a9f314b8b
35 changeset: 0:cb9a9f314b8b
35 user: test
36 user: test
36 date: Thu Jan 01 00:00:00 1970 +0000
37 date: Thu Jan 01 00:00:00 1970 +0000
37 summary: a
38 summary: a
38
39
39
40
40 $ cd ..
41 $ cd ..
41
42
42 Try cloning -r branch:
43 Try cloning -r branch:
43
44
44 $ hg clone -rbr remote local1
45 $ hg clone -rbr remote local1
45 adding changesets
46 adding changesets
46 adding manifests
47 adding manifests
47 adding file changes
48 adding file changes
48 added 3 changesets with 2 changes to 2 files
49 added 3 changesets with 2 changes to 2 files
49 updating to branch br
50 updating to branch br
50 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
51
52
52 $ hg -R local1 parents
53 $ hg -R local1 parents
53 changeset: 2:ae3d9c30ec50
54 changeset: 2:ae3d9c30ec50
54 branch: br
55 branch: br
55 tag: tip
56 tag: tip
56 user: test
57 user: test
57 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
58 summary: c
59 summary: c
59
60
60
61
61 Try cloning -rother clone#branch:
62 Try cloning -rother clone#branch:
62
63
63 $ hg clone -r0 remote#br local2
64 $ hg clone -r0 remote#br local2
64 adding changesets
65 adding changesets
65 adding manifests
66 adding manifests
66 adding file changes
67 adding file changes
67 added 3 changesets with 2 changes to 2 files
68 added 3 changesets with 2 changes to 2 files
68 updating to branch default
69 updating to branch default
69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70
71
71 $ hg -R local2 parents
72 $ hg -R local2 parents
72 changeset: 0:cb9a9f314b8b
73 changeset: 0:cb9a9f314b8b
73 user: test
74 user: test
74 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
75 summary: a
76 summary: a
76
77
77
78
78 Try cloning -r1 clone#branch:
79 Try cloning -r1 clone#branch:
79
80
80 $ hg clone -r1 remote#br local3
81 $ hg clone -r1 remote#br local3
81 adding changesets
82 adding changesets
82 adding manifests
83 adding manifests
83 adding file changes
84 adding file changes
84 added 3 changesets with 2 changes to 2 files
85 added 3 changesets with 2 changes to 2 files
85 updating to branch br
86 updating to branch br
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87
88
88 $ hg -R local3 parents
89 $ hg -R local3 parents
89 changeset: 1:3f7f930ca414
90 changeset: 1:3f7f930ca414
90 branch: br
91 branch: br
91 user: test
92 user: test
92 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
93 summary: b
94 summary: b
94
95
95
96
@@ -1,29 +1,30 b''
1 http://mercurial.selenic.com/bts/issue619
1 http://mercurial.selenic.com/bts/issue619
2
2
3 $ hg init
3 $ hg init
4 $ echo a > a
4 $ echo a > a
5 $ hg ci -Ama
5 $ hg ci -Ama
6 adding a
6 adding a
7
7
8 $ echo b > b
8 $ echo b > b
9 $ hg branch b
9 $ hg branch b
10 marked working directory as branch b
10 marked working directory as branch b
11 (branches are permanent and global, did you want a bookmark?)
11 $ hg ci -Amb
12 $ hg ci -Amb
12 adding b
13 adding b
13
14
14 $ hg co -C 0
15 $ hg co -C 0
15 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
16 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
16
17
17 Fast-forward:
18 Fast-forward:
18
19
19 $ hg merge b
20 $ hg merge b
20 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 (branch merge, don't forget to commit)
22 (branch merge, don't forget to commit)
22 $ hg ci -Ammerge
23 $ hg ci -Ammerge
23
24
24 Bogus fast-forward should fail:
25 Bogus fast-forward should fail:
25
26
26 $ hg merge b
27 $ hg merge b
27 abort: merging with a working directory ancestor has no effect
28 abort: merging with a working directory ancestor has no effect
28 [255]
29 [255]
29
30
@@ -1,38 +1,39 b''
1 http://mercurial.selenic.com/bts/issue842
1 http://mercurial.selenic.com/bts/issue842
2
2
3 $ hg init
3 $ hg init
4 $ echo foo > a
4 $ echo foo > a
5 $ hg ci -Ama
5 $ hg ci -Ama
6 adding a
6 adding a
7
7
8 $ hg up -r0000
8 $ hg up -r0000
9 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
9 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
10
10
11 $ echo bar > a
11 $ echo bar > a
12
12
13 Should issue new head warning:
13 Should issue new head warning:
14
14
15 $ hg ci -Amb
15 $ hg ci -Amb
16 adding a
16 adding a
17 created new head
17 created new head
18
18
19 $ hg up -r0000
19 $ hg up -r0000
20 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
20 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
21
21
22 $ echo stuffy > a
22 $ echo stuffy > a
23
23
24 Should not issue new head warning:
24 Should not issue new head warning:
25
25
26 $ hg ci -q -Amc
26 $ hg ci -q -Amc
27
27
28 $ hg up -r0000
28 $ hg up -r0000
29 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
29 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
30
30
31 $ echo crap > a
31 $ echo crap > a
32 $ hg branch testing
32 $ hg branch testing
33 marked working directory as branch testing
33 marked working directory as branch testing
34 (branches are permanent and global, did you want a bookmark?)
34
35
35 Should not issue warning:
36 Should not issue warning:
36
37
37 $ hg ci -q -Amd
38 $ hg ci -q -Amd
38
39
@@ -1,1088 +1,1089 b''
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
2
2
3 $ cat <<EOF >> $HGRCPATH
3 $ cat <<EOF >> $HGRCPATH
4 > [extensions]
4 > [extensions]
5 > keyword =
5 > keyword =
6 > mq =
6 > mq =
7 > notify =
7 > notify =
8 > record =
8 > record =
9 > transplant =
9 > transplant =
10 > [ui]
10 > [ui]
11 > interactive = true
11 > interactive = true
12 > EOF
12 > EOF
13
13
14 Run kwdemo before [keyword] files are set up
14 Run kwdemo before [keyword] files are set up
15 as it would succeed without uisetup otherwise
15 as it would succeed without uisetup otherwise
16
16
17 $ hg --quiet kwdemo
17 $ hg --quiet kwdemo
18 [extensions]
18 [extensions]
19 keyword =
19 keyword =
20 [keyword]
20 [keyword]
21 demo.txt =
21 demo.txt =
22 [keywordset]
22 [keywordset]
23 svn = False
23 svn = False
24 [keywordmaps]
24 [keywordmaps]
25 Author = {author|user}
25 Author = {author|user}
26 Date = {date|utcdate}
26 Date = {date|utcdate}
27 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
27 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
28 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
28 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
29 RCSFile = {file|basename},v
29 RCSFile = {file|basename},v
30 RCSfile = {file|basename},v
30 RCSfile = {file|basename},v
31 Revision = {node|short}
31 Revision = {node|short}
32 Source = {root}/{file},v
32 Source = {root}/{file},v
33 $Author: test $
33 $Author: test $
34 $Date: ????/??/?? ??:??:?? $ (glob)
34 $Date: ????/??/?? ??:??:?? $ (glob)
35 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
35 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
36 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
36 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
37 $RCSFile: demo.txt,v $
37 $RCSFile: demo.txt,v $
38 $RCSfile: demo.txt,v $
38 $RCSfile: demo.txt,v $
39 $Revision: ???????????? $ (glob)
39 $Revision: ???????????? $ (glob)
40 $Source: */demo.txt,v $ (glob)
40 $Source: */demo.txt,v $ (glob)
41
41
42 $ hg --quiet kwdemo "Branch = {branches}"
42 $ hg --quiet kwdemo "Branch = {branches}"
43 [extensions]
43 [extensions]
44 keyword =
44 keyword =
45 [keyword]
45 [keyword]
46 demo.txt =
46 demo.txt =
47 [keywordset]
47 [keywordset]
48 svn = False
48 svn = False
49 [keywordmaps]
49 [keywordmaps]
50 Branch = {branches}
50 Branch = {branches}
51 $Branch: demobranch $
51 $Branch: demobranch $
52
52
53 $ cat <<EOF >> $HGRCPATH
53 $ cat <<EOF >> $HGRCPATH
54 > [keyword]
54 > [keyword]
55 > ** =
55 > ** =
56 > b = ignore
56 > b = ignore
57 > i = ignore
57 > i = ignore
58 > [hooks]
58 > [hooks]
59 > EOF
59 > EOF
60 $ cp $HGRCPATH $HGRCPATH.nohooks
60 $ cp $HGRCPATH $HGRCPATH.nohooks
61 > cat <<EOF >> $HGRCPATH
61 > cat <<EOF >> $HGRCPATH
62 > commit=
62 > commit=
63 > commit.test=cp a hooktest
63 > commit.test=cp a hooktest
64 > EOF
64 > EOF
65
65
66 $ hg init Test-bndl
66 $ hg init Test-bndl
67 $ cd Test-bndl
67 $ cd Test-bndl
68
68
69 kwshrink should exit silently in empty/invalid repo
69 kwshrink should exit silently in empty/invalid repo
70
70
71 $ hg kwshrink
71 $ hg kwshrink
72
72
73 Symlinks cannot be created on Windows.
73 Symlinks cannot be created on Windows.
74 A bundle to test this was made with:
74 A bundle to test this was made with:
75 hg init t
75 hg init t
76 cd t
76 cd t
77 echo a > a
77 echo a > a
78 ln -s a sym
78 ln -s a sym
79 hg add sym
79 hg add sym
80 hg ci -m addsym -u mercurial
80 hg ci -m addsym -u mercurial
81 hg bundle --base null ../test-keyword.hg
81 hg bundle --base null ../test-keyword.hg
82
82
83 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
83 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
84 pulling from *test-keyword.hg (glob)
84 pulling from *test-keyword.hg (glob)
85 requesting all changes
85 requesting all changes
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 1 changesets with 1 changes to 1 files
89 added 1 changesets with 1 changes to 1 files
90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91
91
92 $ echo 'expand $Id$' > a
92 $ echo 'expand $Id$' > a
93 $ echo 'do not process $Id:' >> a
93 $ echo 'do not process $Id:' >> a
94 $ echo 'xxx $' >> a
94 $ echo 'xxx $' >> a
95 $ echo 'ignore $Id$' > b
95 $ echo 'ignore $Id$' > b
96
96
97 Output files as they were created
97 Output files as they were created
98
98
99 $ cat a b
99 $ cat a b
100 expand $Id$
100 expand $Id$
101 do not process $Id:
101 do not process $Id:
102 xxx $
102 xxx $
103 ignore $Id$
103 ignore $Id$
104
104
105 no kwfiles
105 no kwfiles
106
106
107 $ hg kwfiles
107 $ hg kwfiles
108
108
109 untracked candidates
109 untracked candidates
110
110
111 $ hg -v kwfiles --unknown
111 $ hg -v kwfiles --unknown
112 k a
112 k a
113
113
114 Add files and check status
114 Add files and check status
115
115
116 $ hg addremove
116 $ hg addremove
117 adding a
117 adding a
118 adding b
118 adding b
119 $ hg status
119 $ hg status
120 A a
120 A a
121 A b
121 A b
122
122
123
123
124 Default keyword expansion including commit hook
124 Default keyword expansion including commit hook
125 Interrupted commit should not change state or run commit hook
125 Interrupted commit should not change state or run commit hook
126
126
127 $ hg --debug commit
127 $ hg --debug commit
128 abort: empty commit message
128 abort: empty commit message
129 [255]
129 [255]
130 $ hg status
130 $ hg status
131 A a
131 A a
132 A b
132 A b
133
133
134 Commit with several checks
134 Commit with several checks
135
135
136 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
136 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
137 a
137 a
138 b
138 b
139 overwriting a expanding keywords
139 overwriting a expanding keywords
140 running hook commit.test: cp a hooktest
140 running hook commit.test: cp a hooktest
141 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
141 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
142 $ hg status
142 $ hg status
143 ? hooktest
143 ? hooktest
144 $ hg debugrebuildstate
144 $ hg debugrebuildstate
145 $ hg --quiet identify
145 $ hg --quiet identify
146 ef63ca68695b
146 ef63ca68695b
147
147
148 cat files in working directory with keywords expanded
148 cat files in working directory with keywords expanded
149
149
150 $ cat a b
150 $ cat a b
151 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
151 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
152 do not process $Id:
152 do not process $Id:
153 xxx $
153 xxx $
154 ignore $Id$
154 ignore $Id$
155
155
156 hg cat files and symlink, no expansion
156 hg cat files and symlink, no expansion
157
157
158 $ hg cat sym a b && echo
158 $ hg cat sym a b && echo
159 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
159 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
160 do not process $Id:
160 do not process $Id:
161 xxx $
161 xxx $
162 ignore $Id$
162 ignore $Id$
163 a
163 a
164
164
165 Test hook execution
165 Test hook execution
166
166
167 $ diff a hooktest
167 $ diff a hooktest
168
168
169 $ cp $HGRCPATH.nohooks $HGRCPATH
169 $ cp $HGRCPATH.nohooks $HGRCPATH
170 $ rm hooktest
170 $ rm hooktest
171
171
172 bundle
172 bundle
173
173
174 $ hg bundle --base null ../kw.hg
174 $ hg bundle --base null ../kw.hg
175 2 changesets found
175 2 changesets found
176 $ cd ..
176 $ cd ..
177 $ hg init Test
177 $ hg init Test
178 $ cd Test
178 $ cd Test
179
179
180 Notify on pull to check whether keywords stay as is in email
180 Notify on pull to check whether keywords stay as is in email
181 ie. if patch.diff wrapper acts as it should
181 ie. if patch.diff wrapper acts as it should
182
182
183 $ cat <<EOF >> $HGRCPATH
183 $ cat <<EOF >> $HGRCPATH
184 > [hooks]
184 > [hooks]
185 > incoming.notify = python:hgext.notify.hook
185 > incoming.notify = python:hgext.notify.hook
186 > [notify]
186 > [notify]
187 > sources = pull
187 > sources = pull
188 > diffstat = False
188 > diffstat = False
189 > maxsubject = 15
189 > maxsubject = 15
190 > [reposubs]
190 > [reposubs]
191 > * = Test
191 > * = Test
192 > EOF
192 > EOF
193
193
194 Pull from bundle and trigger notify
194 Pull from bundle and trigger notify
195
195
196 $ hg pull -u ../kw.hg
196 $ hg pull -u ../kw.hg
197 pulling from ../kw.hg
197 pulling from ../kw.hg
198 requesting all changes
198 requesting all changes
199 adding changesets
199 adding changesets
200 adding manifests
200 adding manifests
201 adding file changes
201 adding file changes
202 added 2 changesets with 3 changes to 3 files
202 added 2 changesets with 3 changes to 3 files
203 Content-Type: text/plain; charset="us-ascii"
203 Content-Type: text/plain; charset="us-ascii"
204 MIME-Version: 1.0
204 MIME-Version: 1.0
205 Content-Transfer-Encoding: 7bit
205 Content-Transfer-Encoding: 7bit
206 Date: * (glob)
206 Date: * (glob)
207 Subject: changeset in...
207 Subject: changeset in...
208 From: mercurial
208 From: mercurial
209 X-Hg-Notification: changeset a2392c293916
209 X-Hg-Notification: changeset a2392c293916
210 Message-Id: <hg.a2392c293916*> (glob)
210 Message-Id: <hg.a2392c293916*> (glob)
211 To: Test
211 To: Test
212
212
213 changeset a2392c293916 in $TESTTMP/Test (glob)
213 changeset a2392c293916 in $TESTTMP/Test (glob)
214 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
214 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
215 description:
215 description:
216 addsym
216 addsym
217
217
218 diffs (6 lines):
218 diffs (6 lines):
219
219
220 diff -r 000000000000 -r a2392c293916 sym
220 diff -r 000000000000 -r a2392c293916 sym
221 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
221 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
222 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
222 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
223 @@ -0,0 +1,1 @@
223 @@ -0,0 +1,1 @@
224 +a
224 +a
225 \ No newline at end of file
225 \ No newline at end of file
226 Content-Type: text/plain; charset="us-ascii"
226 Content-Type: text/plain; charset="us-ascii"
227 MIME-Version: 1.0
227 MIME-Version: 1.0
228 Content-Transfer-Encoding: 7bit
228 Content-Transfer-Encoding: 7bit
229 Date:* (glob)
229 Date:* (glob)
230 Subject: changeset in...
230 Subject: changeset in...
231 From: User Name <user@example.com>
231 From: User Name <user@example.com>
232 X-Hg-Notification: changeset ef63ca68695b
232 X-Hg-Notification: changeset ef63ca68695b
233 Message-Id: <hg.ef63ca68695b*> (glob)
233 Message-Id: <hg.ef63ca68695b*> (glob)
234 To: Test
234 To: Test
235
235
236 changeset ef63ca68695b in $TESTTMP/Test (glob)
236 changeset ef63ca68695b in $TESTTMP/Test (glob)
237 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
237 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
238 description:
238 description:
239 absym
239 absym
240
240
241 diffs (12 lines):
241 diffs (12 lines):
242
242
243 diff -r a2392c293916 -r ef63ca68695b a
243 diff -r a2392c293916 -r ef63ca68695b a
244 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
244 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
245 +++ b/a Thu Jan 01 00:00:00 1970 +0000
245 +++ b/a Thu Jan 01 00:00:00 1970 +0000
246 @@ -0,0 +1,3 @@
246 @@ -0,0 +1,3 @@
247 +expand $Id$
247 +expand $Id$
248 +do not process $Id:
248 +do not process $Id:
249 +xxx $
249 +xxx $
250 diff -r a2392c293916 -r ef63ca68695b b
250 diff -r a2392c293916 -r ef63ca68695b b
251 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
251 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
252 +++ b/b Thu Jan 01 00:00:00 1970 +0000
252 +++ b/b Thu Jan 01 00:00:00 1970 +0000
253 @@ -0,0 +1,1 @@
253 @@ -0,0 +1,1 @@
254 +ignore $Id$
254 +ignore $Id$
255 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
255 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
256
256
257 $ cp $HGRCPATH.nohooks $HGRCPATH
257 $ cp $HGRCPATH.nohooks $HGRCPATH
258
258
259 Touch files and check with status
259 Touch files and check with status
260
260
261 $ touch a b
261 $ touch a b
262 $ hg status
262 $ hg status
263
263
264 Update and expand
264 Update and expand
265
265
266 $ rm sym a b
266 $ rm sym a b
267 $ hg update -C
267 $ hg update -C
268 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 $ cat a b
269 $ cat a b
270 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
270 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
271 do not process $Id:
271 do not process $Id:
272 xxx $
272 xxx $
273 ignore $Id$
273 ignore $Id$
274
274
275 Check whether expansion is filewise and file mode is preserved
275 Check whether expansion is filewise and file mode is preserved
276
276
277 $ echo '$Id$' > c
277 $ echo '$Id$' > c
278 $ echo 'tests for different changenodes' >> c
278 $ echo 'tests for different changenodes' >> c
279 $ chmod 600 c
279 $ chmod 600 c
280 $ ls -l c | cut -b 1-10
280 $ ls -l c | cut -b 1-10
281 -rw-------
281 -rw-------
282
282
283 commit file c
283 commit file c
284
284
285 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
285 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
286 adding c
286 adding c
287 $ ls -l c | cut -b 1-10
287 $ ls -l c | cut -b 1-10
288 -rw-------
288 -rw-------
289
289
290 force expansion
290 force expansion
291
291
292 $ hg -v kwexpand
292 $ hg -v kwexpand
293 overwriting a expanding keywords
293 overwriting a expanding keywords
294 overwriting c expanding keywords
294 overwriting c expanding keywords
295
295
296 compare changenodes in a and c
296 compare changenodes in a and c
297
297
298 $ cat a c
298 $ cat a c
299 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
299 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
300 do not process $Id:
300 do not process $Id:
301 xxx $
301 xxx $
302 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
302 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
303 tests for different changenodes
303 tests for different changenodes
304
304
305 record
305 record
306
306
307 $ echo '$Id$' > r
307 $ echo '$Id$' > r
308 $ hg add r
308 $ hg add r
309
309
310 record chunk
310 record chunk
311
311
312 >>> lines = open('a').readlines()
312 >>> lines = open('a').readlines()
313 >>> lines.insert(1, 'foo\n')
313 >>> lines.insert(1, 'foo\n')
314 >>> lines.append('bar\n')
314 >>> lines.append('bar\n')
315 >>> open('a', 'w').writelines(lines)
315 >>> open('a', 'w').writelines(lines)
316 $ hg record -d '1 10' -m rectest a<<EOF
316 $ hg record -d '1 10' -m rectest a<<EOF
317 > y
317 > y
318 > y
318 > y
319 > n
319 > n
320 > EOF
320 > EOF
321 diff --git a/a b/a
321 diff --git a/a b/a
322 2 hunks, 2 lines changed
322 2 hunks, 2 lines changed
323 examine changes to 'a'? [Ynsfdaq?]
323 examine changes to 'a'? [Ynsfdaq?]
324 @@ -1,3 +1,4 @@
324 @@ -1,3 +1,4 @@
325 expand $Id$
325 expand $Id$
326 +foo
326 +foo
327 do not process $Id:
327 do not process $Id:
328 xxx $
328 xxx $
329 record change 1/2 to 'a'? [Ynsfdaq?]
329 record change 1/2 to 'a'? [Ynsfdaq?]
330 @@ -2,2 +3,3 @@
330 @@ -2,2 +3,3 @@
331 do not process $Id:
331 do not process $Id:
332 xxx $
332 xxx $
333 +bar
333 +bar
334 record change 2/2 to 'a'? [Ynsfdaq?]
334 record change 2/2 to 'a'? [Ynsfdaq?]
335
335
336 $ hg identify
336 $ hg identify
337 d17e03c92c97+ tip
337 d17e03c92c97+ tip
338 $ hg status
338 $ hg status
339 M a
339 M a
340 A r
340 A r
341
341
342 Cat modified file a
342 Cat modified file a
343
343
344 $ cat a
344 $ cat a
345 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
345 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
346 foo
346 foo
347 do not process $Id:
347 do not process $Id:
348 xxx $
348 xxx $
349 bar
349 bar
350
350
351 Diff remaining chunk
351 Diff remaining chunk
352
352
353 $ hg diff a
353 $ hg diff a
354 diff -r d17e03c92c97 a
354 diff -r d17e03c92c97 a
355 --- a/a Wed Dec 31 23:59:51 1969 -0000
355 --- a/a Wed Dec 31 23:59:51 1969 -0000
356 +++ b/a * (glob)
356 +++ b/a * (glob)
357 @@ -2,3 +2,4 @@
357 @@ -2,3 +2,4 @@
358 foo
358 foo
359 do not process $Id:
359 do not process $Id:
360 xxx $
360 xxx $
361 +bar
361 +bar
362
362
363 $ hg rollback
363 $ hg rollback
364 repository tip rolled back to revision 2 (undo commit)
364 repository tip rolled back to revision 2 (undo commit)
365 working directory now based on revision 2
365 working directory now based on revision 2
366
366
367 Record all chunks in file a
367 Record all chunks in file a
368
368
369 $ echo foo > msg
369 $ echo foo > msg
370
370
371 - do not use "hg record -m" here!
371 - do not use "hg record -m" here!
372
372
373 $ hg record -l msg -d '1 11' a<<EOF
373 $ hg record -l msg -d '1 11' a<<EOF
374 > y
374 > y
375 > y
375 > y
376 > y
376 > y
377 > EOF
377 > EOF
378 diff --git a/a b/a
378 diff --git a/a b/a
379 2 hunks, 2 lines changed
379 2 hunks, 2 lines changed
380 examine changes to 'a'? [Ynsfdaq?]
380 examine changes to 'a'? [Ynsfdaq?]
381 @@ -1,3 +1,4 @@
381 @@ -1,3 +1,4 @@
382 expand $Id$
382 expand $Id$
383 +foo
383 +foo
384 do not process $Id:
384 do not process $Id:
385 xxx $
385 xxx $
386 record change 1/2 to 'a'? [Ynsfdaq?]
386 record change 1/2 to 'a'? [Ynsfdaq?]
387 @@ -2,2 +3,3 @@
387 @@ -2,2 +3,3 @@
388 do not process $Id:
388 do not process $Id:
389 xxx $
389 xxx $
390 +bar
390 +bar
391 record change 2/2 to 'a'? [Ynsfdaq?]
391 record change 2/2 to 'a'? [Ynsfdaq?]
392
392
393 File a should be clean
393 File a should be clean
394
394
395 $ hg status -A a
395 $ hg status -A a
396 C a
396 C a
397
397
398 rollback and revert expansion
398 rollback and revert expansion
399
399
400 $ cat a
400 $ cat a
401 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
401 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
402 foo
402 foo
403 do not process $Id:
403 do not process $Id:
404 xxx $
404 xxx $
405 bar
405 bar
406 $ hg --verbose rollback
406 $ hg --verbose rollback
407 repository tip rolled back to revision 2 (undo commit)
407 repository tip rolled back to revision 2 (undo commit)
408 working directory now based on revision 2
408 working directory now based on revision 2
409 overwriting a expanding keywords
409 overwriting a expanding keywords
410 $ hg status a
410 $ hg status a
411 M a
411 M a
412 $ cat a
412 $ cat a
413 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
413 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
414 foo
414 foo
415 do not process $Id:
415 do not process $Id:
416 xxx $
416 xxx $
417 bar
417 bar
418 $ echo '$Id$' > y
418 $ echo '$Id$' > y
419 $ echo '$Id$' > z
419 $ echo '$Id$' > z
420 $ hg add y
420 $ hg add y
421 $ hg commit -Am "rollback only" z
421 $ hg commit -Am "rollback only" z
422 $ cat z
422 $ cat z
423 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
423 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
424 $ hg --verbose rollback
424 $ hg --verbose rollback
425 repository tip rolled back to revision 2 (undo commit)
425 repository tip rolled back to revision 2 (undo commit)
426 working directory now based on revision 2
426 working directory now based on revision 2
427 overwriting z shrinking keywords
427 overwriting z shrinking keywords
428
428
429 Only z should be overwritten
429 Only z should be overwritten
430
430
431 $ hg status a y z
431 $ hg status a y z
432 M a
432 M a
433 A y
433 A y
434 A z
434 A z
435 $ cat z
435 $ cat z
436 $Id$
436 $Id$
437 $ hg forget y z
437 $ hg forget y z
438 $ rm y z
438 $ rm y z
439
439
440 record added file alone
440 record added file alone
441
441
442 $ hg -v record -l msg -d '1 12' r<<EOF
442 $ hg -v record -l msg -d '1 12' r<<EOF
443 > y
443 > y
444 > EOF
444 > EOF
445 diff --git a/r b/r
445 diff --git a/r b/r
446 new file mode 100644
446 new file mode 100644
447 examine changes to 'r'? [Ynsfdaq?]
447 examine changes to 'r'? [Ynsfdaq?]
448 r
448 r
449 committed changeset 3:899491280810
449 committed changeset 3:899491280810
450 overwriting r expanding keywords
450 overwriting r expanding keywords
451 - status call required for dirstate.normallookup() check
451 - status call required for dirstate.normallookup() check
452 $ hg status r
452 $ hg status r
453 $ hg --verbose rollback
453 $ hg --verbose rollback
454 repository tip rolled back to revision 2 (undo commit)
454 repository tip rolled back to revision 2 (undo commit)
455 working directory now based on revision 2
455 working directory now based on revision 2
456 overwriting r shrinking keywords
456 overwriting r shrinking keywords
457 $ hg forget r
457 $ hg forget r
458 $ rm msg r
458 $ rm msg r
459 $ hg update -C
459 $ hg update -C
460 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
460 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
461
461
462 record added keyword ignored file
462 record added keyword ignored file
463
463
464 $ echo '$Id$' > i
464 $ echo '$Id$' > i
465 $ hg add i
465 $ hg add i
466 $ hg --verbose record -d '1 13' -m recignored<<EOF
466 $ hg --verbose record -d '1 13' -m recignored<<EOF
467 > y
467 > y
468 > EOF
468 > EOF
469 diff --git a/i b/i
469 diff --git a/i b/i
470 new file mode 100644
470 new file mode 100644
471 examine changes to 'i'? [Ynsfdaq?]
471 examine changes to 'i'? [Ynsfdaq?]
472 i
472 i
473 committed changeset 3:5f40fe93bbdc
473 committed changeset 3:5f40fe93bbdc
474 $ cat i
474 $ cat i
475 $Id$
475 $Id$
476 $ hg -q rollback
476 $ hg -q rollback
477 $ hg forget i
477 $ hg forget i
478 $ rm i
478 $ rm i
479
479
480 Test patch queue repo
480 Test patch queue repo
481
481
482 $ hg init --mq
482 $ hg init --mq
483 $ hg qimport -r tip -n mqtest.diff
483 $ hg qimport -r tip -n mqtest.diff
484 $ hg commit --mq -m mqtest
484 $ hg commit --mq -m mqtest
485
485
486 Keywords should not be expanded in patch
486 Keywords should not be expanded in patch
487
487
488 $ cat .hg/patches/mqtest.diff
488 $ cat .hg/patches/mqtest.diff
489 # HG changeset patch
489 # HG changeset patch
490 # User User Name <user@example.com>
490 # User User Name <user@example.com>
491 # Date 1 0
491 # Date 1 0
492 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
492 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
493 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
493 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
494 cndiff
494 cndiff
495
495
496 diff -r ef63ca68695b -r 40a904bbbe4c c
496 diff -r ef63ca68695b -r 40a904bbbe4c c
497 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
497 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
498 +++ b/c Thu Jan 01 00:00:01 1970 +0000
498 +++ b/c Thu Jan 01 00:00:01 1970 +0000
499 @@ -0,0 +1,2 @@
499 @@ -0,0 +1,2 @@
500 +$Id$
500 +$Id$
501 +tests for different changenodes
501 +tests for different changenodes
502
502
503 $ hg qpop
503 $ hg qpop
504 popping mqtest.diff
504 popping mqtest.diff
505 patch queue now empty
505 patch queue now empty
506
506
507 qgoto, implying qpush, should expand
507 qgoto, implying qpush, should expand
508
508
509 $ hg qgoto mqtest.diff
509 $ hg qgoto mqtest.diff
510 applying mqtest.diff
510 applying mqtest.diff
511 now at: mqtest.diff
511 now at: mqtest.diff
512 $ cat c
512 $ cat c
513 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
513 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
514 tests for different changenodes
514 tests for different changenodes
515 $ hg cat c
515 $ hg cat c
516 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
516 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
517 tests for different changenodes
517 tests for different changenodes
518
518
519 Keywords should not be expanded in filelog
519 Keywords should not be expanded in filelog
520
520
521 $ hg --config 'extensions.keyword=!' cat c
521 $ hg --config 'extensions.keyword=!' cat c
522 $Id$
522 $Id$
523 tests for different changenodes
523 tests for different changenodes
524
524
525 qpop and move on
525 qpop and move on
526
526
527 $ hg qpop
527 $ hg qpop
528 popping mqtest.diff
528 popping mqtest.diff
529 patch queue now empty
529 patch queue now empty
530
530
531 Copy and show added kwfiles
531 Copy and show added kwfiles
532
532
533 $ hg cp a c
533 $ hg cp a c
534 $ hg kwfiles
534 $ hg kwfiles
535 a
535 a
536 c
536 c
537
537
538 Commit and show expansion in original and copy
538 Commit and show expansion in original and copy
539
539
540 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
540 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
541 c
541 c
542 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
542 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
543 overwriting c expanding keywords
543 overwriting c expanding keywords
544 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
544 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
545 $ cat a c
545 $ cat a c
546 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
546 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
547 do not process $Id:
547 do not process $Id:
548 xxx $
548 xxx $
549 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
549 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
550 do not process $Id:
550 do not process $Id:
551 xxx $
551 xxx $
552
552
553 Touch copied c and check its status
553 Touch copied c and check its status
554
554
555 $ touch c
555 $ touch c
556 $ hg status
556 $ hg status
557
557
558 Copy kwfile to keyword ignored file unexpanding keywords
558 Copy kwfile to keyword ignored file unexpanding keywords
559
559
560 $ hg --verbose copy a i
560 $ hg --verbose copy a i
561 copying a to i
561 copying a to i
562 overwriting i shrinking keywords
562 overwriting i shrinking keywords
563 $ head -n 1 i
563 $ head -n 1 i
564 expand $Id$
564 expand $Id$
565 $ hg forget i
565 $ hg forget i
566 $ rm i
566 $ rm i
567
567
568 Copy ignored file to ignored file: no overwriting
568 Copy ignored file to ignored file: no overwriting
569
569
570 $ hg --verbose copy b i
570 $ hg --verbose copy b i
571 copying b to i
571 copying b to i
572 $ hg forget i
572 $ hg forget i
573 $ rm i
573 $ rm i
574
574
575 cp symlink file; hg cp -A symlink file (part1)
575 cp symlink file; hg cp -A symlink file (part1)
576 - copied symlink points to kwfile: overwrite
576 - copied symlink points to kwfile: overwrite
577
577
578 $ cp sym i
578 $ cp sym i
579 $ ls -l i
579 $ ls -l i
580 -rw-r--r--* (glob)
580 -rw-r--r--* (glob)
581 $ head -1 i
581 $ head -1 i
582 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
582 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
583 $ hg copy --after --verbose sym i
583 $ hg copy --after --verbose sym i
584 copying sym to i
584 copying sym to i
585 overwriting i shrinking keywords
585 overwriting i shrinking keywords
586 $ head -1 i
586 $ head -1 i
587 expand $Id$
587 expand $Id$
588 $ hg forget i
588 $ hg forget i
589 $ rm i
589 $ rm i
590
590
591 Test different options of hg kwfiles
591 Test different options of hg kwfiles
592
592
593 $ hg kwfiles
593 $ hg kwfiles
594 a
594 a
595 c
595 c
596 $ hg -v kwfiles --ignore
596 $ hg -v kwfiles --ignore
597 I b
597 I b
598 I sym
598 I sym
599 $ hg kwfiles --all
599 $ hg kwfiles --all
600 K a
600 K a
601 K c
601 K c
602 I b
602 I b
603 I sym
603 I sym
604
604
605 Diff specific revision
605 Diff specific revision
606
606
607 $ hg diff --rev 1
607 $ hg diff --rev 1
608 diff -r ef63ca68695b c
608 diff -r ef63ca68695b c
609 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
609 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
610 +++ b/c * (glob)
610 +++ b/c * (glob)
611 @@ -0,0 +1,3 @@
611 @@ -0,0 +1,3 @@
612 +expand $Id$
612 +expand $Id$
613 +do not process $Id:
613 +do not process $Id:
614 +xxx $
614 +xxx $
615
615
616 Status after rollback:
616 Status after rollback:
617
617
618 $ hg rollback
618 $ hg rollback
619 repository tip rolled back to revision 1 (undo commit)
619 repository tip rolled back to revision 1 (undo commit)
620 working directory now based on revision 1
620 working directory now based on revision 1
621 $ hg status
621 $ hg status
622 A c
622 A c
623 $ hg update --clean
623 $ hg update --clean
624 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
624 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
625
625
626 cp symlink file; hg cp -A symlink file (part2)
626 cp symlink file; hg cp -A symlink file (part2)
627 - copied symlink points to kw ignored file: do not overwrite
627 - copied symlink points to kw ignored file: do not overwrite
628
628
629 $ cat a > i
629 $ cat a > i
630 $ ln -s i symignored
630 $ ln -s i symignored
631 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
631 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
632 $ cp symignored x
632 $ cp symignored x
633 $ hg copy --after --verbose symignored x
633 $ hg copy --after --verbose symignored x
634 copying symignored to x
634 copying symignored to x
635 $ head -n 1 x
635 $ head -n 1 x
636 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
636 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
637 $ hg forget x
637 $ hg forget x
638 $ rm x
638 $ rm x
639
639
640 $ hg rollback
640 $ hg rollback
641 repository tip rolled back to revision 1 (undo commit)
641 repository tip rolled back to revision 1 (undo commit)
642 working directory now based on revision 1
642 working directory now based on revision 1
643 $ hg update --clean
643 $ hg update --clean
644 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
644 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
645 $ rm i symignored
645 $ rm i symignored
646
646
647 Custom keywordmaps as argument to kwdemo
647 Custom keywordmaps as argument to kwdemo
648
648
649 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
649 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
650 [extensions]
650 [extensions]
651 keyword =
651 keyword =
652 [keyword]
652 [keyword]
653 ** =
653 ** =
654 b = ignore
654 b = ignore
655 demo.txt =
655 demo.txt =
656 i = ignore
656 i = ignore
657 [keywordset]
657 [keywordset]
658 svn = False
658 svn = False
659 [keywordmaps]
659 [keywordmaps]
660 Xinfo = {author}: {desc}
660 Xinfo = {author}: {desc}
661 $Xinfo: test: hg keyword configuration and expansion example $
661 $Xinfo: test: hg keyword configuration and expansion example $
662
662
663 Configure custom keywordmaps
663 Configure custom keywordmaps
664
664
665 $ cat <<EOF >>$HGRCPATH
665 $ cat <<EOF >>$HGRCPATH
666 > [keywordmaps]
666 > [keywordmaps]
667 > Id = {file} {node|short} {date|rfc822date} {author|user}
667 > Id = {file} {node|short} {date|rfc822date} {author|user}
668 > Xinfo = {author}: {desc}
668 > Xinfo = {author}: {desc}
669 > EOF
669 > EOF
670
670
671 Cat and hg cat files before custom expansion
671 Cat and hg cat files before custom expansion
672
672
673 $ cat a b
673 $ cat a b
674 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
674 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
675 do not process $Id:
675 do not process $Id:
676 xxx $
676 xxx $
677 ignore $Id$
677 ignore $Id$
678 $ hg cat sym a b && echo
678 $ hg cat sym a b && echo
679 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
679 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
680 do not process $Id:
680 do not process $Id:
681 xxx $
681 xxx $
682 ignore $Id$
682 ignore $Id$
683 a
683 a
684
684
685 Write custom keyword and prepare multiline commit message
685 Write custom keyword and prepare multiline commit message
686
686
687 $ echo '$Xinfo$' >> a
687 $ echo '$Xinfo$' >> a
688 $ cat <<EOF >> log
688 $ cat <<EOF >> log
689 > firstline
689 > firstline
690 > secondline
690 > secondline
691 > EOF
691 > EOF
692
692
693 Interrupted commit should not change state
693 Interrupted commit should not change state
694
694
695 $ hg commit
695 $ hg commit
696 abort: empty commit message
696 abort: empty commit message
697 [255]
697 [255]
698 $ hg status
698 $ hg status
699 M a
699 M a
700 ? c
700 ? c
701 ? log
701 ? log
702
702
703 Commit with multiline message and custom expansion
703 Commit with multiline message and custom expansion
704
704
705 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
705 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
706 a
706 a
707 overwriting a expanding keywords
707 overwriting a expanding keywords
708 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
708 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
709 $ rm log
709 $ rm log
710
710
711 Stat, verify and show custom expansion (firstline)
711 Stat, verify and show custom expansion (firstline)
712
712
713 $ hg status
713 $ hg status
714 ? c
714 ? c
715 $ hg verify
715 $ hg verify
716 checking changesets
716 checking changesets
717 checking manifests
717 checking manifests
718 crosschecking files in changesets and manifests
718 crosschecking files in changesets and manifests
719 checking files
719 checking files
720 3 files, 3 changesets, 4 total revisions
720 3 files, 3 changesets, 4 total revisions
721 $ cat a b
721 $ cat a b
722 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
722 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
723 do not process $Id:
723 do not process $Id:
724 xxx $
724 xxx $
725 $Xinfo: User Name <user@example.com>: firstline $
725 $Xinfo: User Name <user@example.com>: firstline $
726 ignore $Id$
726 ignore $Id$
727 $ hg cat sym a b && echo
727 $ hg cat sym a b && echo
728 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
728 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
729 do not process $Id:
729 do not process $Id:
730 xxx $
730 xxx $
731 $Xinfo: User Name <user@example.com>: firstline $
731 $Xinfo: User Name <user@example.com>: firstline $
732 ignore $Id$
732 ignore $Id$
733 a
733 a
734
734
735 annotate
735 annotate
736
736
737 $ hg annotate a
737 $ hg annotate a
738 1: expand $Id$
738 1: expand $Id$
739 1: do not process $Id:
739 1: do not process $Id:
740 1: xxx $
740 1: xxx $
741 2: $Xinfo$
741 2: $Xinfo$
742
742
743 remove with status checks
743 remove with status checks
744
744
745 $ hg debugrebuildstate
745 $ hg debugrebuildstate
746 $ hg remove a
746 $ hg remove a
747 $ hg --debug commit -m rma
747 $ hg --debug commit -m rma
748 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
748 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
749 $ hg status
749 $ hg status
750 ? c
750 ? c
751
751
752 Rollback, revert, and check expansion
752 Rollback, revert, and check expansion
753
753
754 $ hg rollback
754 $ hg rollback
755 repository tip rolled back to revision 2 (undo commit)
755 repository tip rolled back to revision 2 (undo commit)
756 working directory now based on revision 2
756 working directory now based on revision 2
757 $ hg status
757 $ hg status
758 R a
758 R a
759 ? c
759 ? c
760 $ hg revert --no-backup --rev tip a
760 $ hg revert --no-backup --rev tip a
761 $ cat a
761 $ cat a
762 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
762 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
763 do not process $Id:
763 do not process $Id:
764 xxx $
764 xxx $
765 $Xinfo: User Name <user@example.com>: firstline $
765 $Xinfo: User Name <user@example.com>: firstline $
766
766
767 Clone to test global and local configurations
767 Clone to test global and local configurations
768
768
769 $ cd ..
769 $ cd ..
770
770
771 Expansion in destinaton with global configuration
771 Expansion in destinaton with global configuration
772
772
773 $ hg --quiet clone Test globalconf
773 $ hg --quiet clone Test globalconf
774 $ cat globalconf/a
774 $ cat globalconf/a
775 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
775 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
776 do not process $Id:
776 do not process $Id:
777 xxx $
777 xxx $
778 $Xinfo: User Name <user@example.com>: firstline $
778 $Xinfo: User Name <user@example.com>: firstline $
779
779
780 No expansion in destination with local configuration in origin only
780 No expansion in destination with local configuration in origin only
781
781
782 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
782 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
783 $ cat localconf/a
783 $ cat localconf/a
784 expand $Id$
784 expand $Id$
785 do not process $Id:
785 do not process $Id:
786 xxx $
786 xxx $
787 $Xinfo$
787 $Xinfo$
788
788
789 Clone to test incoming
789 Clone to test incoming
790
790
791 $ hg clone -r1 Test Test-a
791 $ hg clone -r1 Test Test-a
792 adding changesets
792 adding changesets
793 adding manifests
793 adding manifests
794 adding file changes
794 adding file changes
795 added 2 changesets with 3 changes to 3 files
795 added 2 changesets with 3 changes to 3 files
796 updating to branch default
796 updating to branch default
797 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
797 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
798 $ cd Test-a
798 $ cd Test-a
799 $ cat <<EOF >> .hg/hgrc
799 $ cat <<EOF >> .hg/hgrc
800 > [paths]
800 > [paths]
801 > default = ../Test
801 > default = ../Test
802 > EOF
802 > EOF
803 $ hg incoming
803 $ hg incoming
804 comparing with $TESTTMP/Test (glob)
804 comparing with $TESTTMP/Test (glob)
805 searching for changes
805 searching for changes
806 changeset: 2:bb948857c743
806 changeset: 2:bb948857c743
807 tag: tip
807 tag: tip
808 user: User Name <user@example.com>
808 user: User Name <user@example.com>
809 date: Thu Jan 01 00:00:02 1970 +0000
809 date: Thu Jan 01 00:00:02 1970 +0000
810 summary: firstline
810 summary: firstline
811
811
812 Imported patch should not be rejected
812 Imported patch should not be rejected
813
813
814 >>> import re
814 >>> import re
815 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
815 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
816 >>> open('a', 'wb').write(text)
816 >>> open('a', 'wb').write(text)
817 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
817 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
818 a
818 a
819 overwriting a expanding keywords
819 overwriting a expanding keywords
820 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
820 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
821 $ hg export -o ../rejecttest.diff tip
821 $ hg export -o ../rejecttest.diff tip
822 $ cd ../Test
822 $ cd ../Test
823 $ hg import ../rejecttest.diff
823 $ hg import ../rejecttest.diff
824 applying ../rejecttest.diff
824 applying ../rejecttest.diff
825 $ cat a b
825 $ cat a b
826 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
826 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
827 do not process $Id: rejecttest
827 do not process $Id: rejecttest
828 xxx $
828 xxx $
829 $Xinfo: User Name <user@example.com>: rejects? $
829 $Xinfo: User Name <user@example.com>: rejects? $
830 ignore $Id$
830 ignore $Id$
831
831
832 $ hg rollback
832 $ hg rollback
833 repository tip rolled back to revision 2 (undo import)
833 repository tip rolled back to revision 2 (undo import)
834 working directory now based on revision 2
834 working directory now based on revision 2
835 $ hg update --clean
835 $ hg update --clean
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
837
838 kwexpand/kwshrink on selected files
838 kwexpand/kwshrink on selected files
839
839
840 $ mkdir x
840 $ mkdir x
841 $ hg copy a x/a
841 $ hg copy a x/a
842 $ hg --verbose kwshrink a
842 $ hg --verbose kwshrink a
843 overwriting a shrinking keywords
843 overwriting a shrinking keywords
844 - sleep required for dirstate.normal() check
844 - sleep required for dirstate.normal() check
845 $ sleep 1
845 $ sleep 1
846 $ hg status a
846 $ hg status a
847 $ hg --verbose kwexpand a
847 $ hg --verbose kwexpand a
848 overwriting a expanding keywords
848 overwriting a expanding keywords
849 $ hg status a
849 $ hg status a
850
850
851 kwexpand x/a should abort
851 kwexpand x/a should abort
852
852
853 $ hg --verbose kwexpand x/a
853 $ hg --verbose kwexpand x/a
854 abort: outstanding uncommitted changes
854 abort: outstanding uncommitted changes
855 [255]
855 [255]
856 $ cd x
856 $ cd x
857 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
857 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
858 x/a
858 x/a
859 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
859 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
860 overwriting x/a expanding keywords
860 overwriting x/a expanding keywords
861 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
861 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
862 $ cat a
862 $ cat a
863 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
863 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
864 do not process $Id:
864 do not process $Id:
865 xxx $
865 xxx $
866 $Xinfo: User Name <user@example.com>: xa $
866 $Xinfo: User Name <user@example.com>: xa $
867
867
868 kwshrink a inside directory x
868 kwshrink a inside directory x
869
869
870 $ hg --verbose kwshrink a
870 $ hg --verbose kwshrink a
871 overwriting x/a shrinking keywords
871 overwriting x/a shrinking keywords
872 $ cat a
872 $ cat a
873 expand $Id$
873 expand $Id$
874 do not process $Id:
874 do not process $Id:
875 xxx $
875 xxx $
876 $Xinfo$
876 $Xinfo$
877 $ cd ..
877 $ cd ..
878
878
879 kwexpand nonexistent
879 kwexpand nonexistent
880
880
881 $ hg kwexpand nonexistent
881 $ hg kwexpand nonexistent
882 nonexistent:* (glob)
882 nonexistent:* (glob)
883
883
884
884
885 hg serve
885 hg serve
886 - expand with hgweb file
886 - expand with hgweb file
887 - no expansion with hgweb annotate/changeset/filediff
887 - no expansion with hgweb annotate/changeset/filediff
888 - check errors
888 - check errors
889
889
890 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
890 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
891 $ cat hg.pid >> $DAEMON_PIDS
891 $ cat hg.pid >> $DAEMON_PIDS
892 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
892 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
893 200 Script output follows
893 200 Script output follows
894
894
895 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
895 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
896 do not process $Id:
896 do not process $Id:
897 xxx $
897 xxx $
898 $Xinfo: User Name <user@example.com>: firstline $
898 $Xinfo: User Name <user@example.com>: firstline $
899 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
899 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
900 200 Script output follows
900 200 Script output follows
901
901
902
902
903 user@1: expand $Id$
903 user@1: expand $Id$
904 user@1: do not process $Id:
904 user@1: do not process $Id:
905 user@1: xxx $
905 user@1: xxx $
906 user@2: $Xinfo$
906 user@2: $Xinfo$
907
907
908
908
909
909
910
910
911 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
911 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
912 200 Script output follows
912 200 Script output follows
913
913
914
914
915 # HG changeset patch
915 # HG changeset patch
916 # User User Name <user@example.com>
916 # User User Name <user@example.com>
917 # Date 3 0
917 # Date 3 0
918 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
918 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
919 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
919 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
920 xa
920 xa
921
921
922 diff -r bb948857c743 -r b4560182a3f9 x/a
922 diff -r bb948857c743 -r b4560182a3f9 x/a
923 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
923 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
924 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
924 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
925 @@ -0,0 +1,4 @@
925 @@ -0,0 +1,4 @@
926 +expand $Id$
926 +expand $Id$
927 +do not process $Id:
927 +do not process $Id:
928 +xxx $
928 +xxx $
929 +$Xinfo$
929 +$Xinfo$
930
930
931 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
931 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
932 200 Script output follows
932 200 Script output follows
933
933
934
934
935 diff -r ef63ca68695b -r bb948857c743 a
935 diff -r ef63ca68695b -r bb948857c743 a
936 --- a/a Thu Jan 01 00:00:00 1970 +0000
936 --- a/a Thu Jan 01 00:00:00 1970 +0000
937 +++ b/a Thu Jan 01 00:00:02 1970 +0000
937 +++ b/a Thu Jan 01 00:00:02 1970 +0000
938 @@ -1,3 +1,4 @@
938 @@ -1,3 +1,4 @@
939 expand $Id$
939 expand $Id$
940 do not process $Id:
940 do not process $Id:
941 xxx $
941 xxx $
942 +$Xinfo$
942 +$Xinfo$
943
943
944
944
945
945
946
946
947 $ cat errors.log
947 $ cat errors.log
948
948
949 Prepare merge and resolve tests
949 Prepare merge and resolve tests
950
950
951 $ echo '$Id$' > m
951 $ echo '$Id$' > m
952 $ hg add m
952 $ hg add m
953 $ hg commit -m 4kw
953 $ hg commit -m 4kw
954 $ echo foo >> m
954 $ echo foo >> m
955 $ hg commit -m 5foo
955 $ hg commit -m 5foo
956
956
957 simplemerge
957 simplemerge
958
958
959 $ hg update 4
959 $ hg update 4
960 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
960 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
961 $ echo foo >> m
961 $ echo foo >> m
962 $ hg commit -m 6foo
962 $ hg commit -m 6foo
963 created new head
963 created new head
964 $ hg merge
964 $ hg merge
965 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
965 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
966 (branch merge, don't forget to commit)
966 (branch merge, don't forget to commit)
967 $ hg commit -m simplemerge
967 $ hg commit -m simplemerge
968 $ cat m
968 $ cat m
969 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
969 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
970 foo
970 foo
971
971
972 conflict: keyword should stay outside conflict zone
972 conflict: keyword should stay outside conflict zone
973
973
974 $ hg update 4
974 $ hg update 4
975 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
975 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
976 $ echo bar >> m
976 $ echo bar >> m
977 $ hg commit -m 8bar
977 $ hg commit -m 8bar
978 created new head
978 created new head
979 $ hg merge
979 $ hg merge
980 merging m
980 merging m
981 warning: conflicts during merge.
981 warning: conflicts during merge.
982 merging m incomplete! (edit conflicts, then use 'hg resolve --mark')
982 merging m incomplete! (edit conflicts, then use 'hg resolve --mark')
983 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
983 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
984 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
984 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
985 [1]
985 [1]
986 $ cat m
986 $ cat m
987 $Id$
987 $Id$
988 <<<<<<< local
988 <<<<<<< local
989 bar
989 bar
990 =======
990 =======
991 foo
991 foo
992 >>>>>>> other
992 >>>>>>> other
993
993
994 resolve to local
994 resolve to local
995
995
996 $ HGMERGE=internal:local hg resolve -a
996 $ HGMERGE=internal:local hg resolve -a
997 $ hg commit -m localresolve
997 $ hg commit -m localresolve
998 $ cat m
998 $ cat m
999 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
999 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
1000 bar
1000 bar
1001
1001
1002 Test restricted mode with transplant -b
1002 Test restricted mode with transplant -b
1003
1003
1004 $ hg update 6
1004 $ hg update 6
1005 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1005 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1006 $ hg branch foo
1006 $ hg branch foo
1007 marked working directory as branch foo
1007 marked working directory as branch foo
1008 (branches are permanent and global, did you want a bookmark?)
1008 $ mv a a.bak
1009 $ mv a a.bak
1009 $ echo foobranch > a
1010 $ echo foobranch > a
1010 $ cat a.bak >> a
1011 $ cat a.bak >> a
1011 $ rm a.bak
1012 $ rm a.bak
1012 $ hg commit -m 9foobranch
1013 $ hg commit -m 9foobranch
1013 $ hg update default
1014 $ hg update default
1014 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1015 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1015 $ hg -y transplant -b foo tip
1016 $ hg -y transplant -b foo tip
1016 applying 4aa30d025d50
1017 applying 4aa30d025d50
1017 4aa30d025d50 transplanted to e00abbf63521
1018 4aa30d025d50 transplanted to e00abbf63521
1018
1019
1019 Expansion in changeset but not in file
1020 Expansion in changeset but not in file
1020
1021
1021 $ hg tip -p
1022 $ hg tip -p
1022 changeset: 11:e00abbf63521
1023 changeset: 11:e00abbf63521
1023 tag: tip
1024 tag: tip
1024 parent: 9:800511b3a22d
1025 parent: 9:800511b3a22d
1025 user: test
1026 user: test
1026 date: Thu Jan 01 00:00:00 1970 +0000
1027 date: Thu Jan 01 00:00:00 1970 +0000
1027 summary: 9foobranch
1028 summary: 9foobranch
1028
1029
1029 diff -r 800511b3a22d -r e00abbf63521 a
1030 diff -r 800511b3a22d -r e00abbf63521 a
1030 --- a/a Thu Jan 01 00:00:00 1970 +0000
1031 --- a/a Thu Jan 01 00:00:00 1970 +0000
1031 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1032 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1032 @@ -1,3 +1,4 @@
1033 @@ -1,3 +1,4 @@
1033 +foobranch
1034 +foobranch
1034 expand $Id$
1035 expand $Id$
1035 do not process $Id:
1036 do not process $Id:
1036 xxx $
1037 xxx $
1037
1038
1038 $ head -n 2 a
1039 $ head -n 2 a
1039 foobranch
1040 foobranch
1040 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1041 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1041
1042
1042 Turn off expansion
1043 Turn off expansion
1043
1044
1044 $ hg -q rollback
1045 $ hg -q rollback
1045 $ hg -q update -C
1046 $ hg -q update -C
1046
1047
1047 kwshrink with unknown file u
1048 kwshrink with unknown file u
1048
1049
1049 $ cp a u
1050 $ cp a u
1050 $ hg --verbose kwshrink
1051 $ hg --verbose kwshrink
1051 overwriting a shrinking keywords
1052 overwriting a shrinking keywords
1052 overwriting m shrinking keywords
1053 overwriting m shrinking keywords
1053 overwriting x/a shrinking keywords
1054 overwriting x/a shrinking keywords
1054
1055
1055 Keywords shrunk in working directory, but not yet disabled
1056 Keywords shrunk in working directory, but not yet disabled
1056 - cat shows unexpanded keywords
1057 - cat shows unexpanded keywords
1057 - hg cat shows expanded keywords
1058 - hg cat shows expanded keywords
1058
1059
1059 $ cat a b
1060 $ cat a b
1060 expand $Id$
1061 expand $Id$
1061 do not process $Id:
1062 do not process $Id:
1062 xxx $
1063 xxx $
1063 $Xinfo$
1064 $Xinfo$
1064 ignore $Id$
1065 ignore $Id$
1065 $ hg cat sym a b && echo
1066 $ hg cat sym a b && echo
1066 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1067 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1067 do not process $Id:
1068 do not process $Id:
1068 xxx $
1069 xxx $
1069 $Xinfo: User Name <user@example.com>: firstline $
1070 $Xinfo: User Name <user@example.com>: firstline $
1070 ignore $Id$
1071 ignore $Id$
1071 a
1072 a
1072
1073
1073 Now disable keyword expansion
1074 Now disable keyword expansion
1074
1075
1075 $ rm "$HGRCPATH"
1076 $ rm "$HGRCPATH"
1076 $ cat a b
1077 $ cat a b
1077 expand $Id$
1078 expand $Id$
1078 do not process $Id:
1079 do not process $Id:
1079 xxx $
1080 xxx $
1080 $Xinfo$
1081 $Xinfo$
1081 ignore $Id$
1082 ignore $Id$
1082 $ hg cat sym a b && echo
1083 $ hg cat sym a b && echo
1083 expand $Id$
1084 expand $Id$
1084 do not process $Id:
1085 do not process $Id:
1085 xxx $
1086 xxx $
1086 $Xinfo$
1087 $Xinfo$
1087 ignore $Id$
1088 ignore $Id$
1088 a
1089 a
@@ -1,1160 +1,1161 b''
1 $ "$TESTDIR/hghave" execbit || exit 80
1 $ "$TESTDIR/hghave" execbit || exit 80
2
2
3 $ hg init a
3 $ hg init a
4
4
5 $ cd a
5 $ cd a
6 $ echo a > a
6 $ echo a > a
7 $ hg ci -Ama -d '1 0'
7 $ hg ci -Ama -d '1 0'
8 adding a
8 adding a
9
9
10 $ hg cp a b
10 $ hg cp a b
11 $ hg ci -mb -d '2 0'
11 $ hg ci -mb -d '2 0'
12
12
13 $ mkdir dir
13 $ mkdir dir
14 $ hg mv b dir
14 $ hg mv b dir
15 $ hg ci -mc -d '3 0'
15 $ hg ci -mc -d '3 0'
16
16
17 $ hg mv a b
17 $ hg mv a b
18 $ echo a > d
18 $ echo a > d
19 $ hg add d
19 $ hg add d
20 $ hg ci -md -d '4 0'
20 $ hg ci -md -d '4 0'
21
21
22 $ hg mv dir/b e
22 $ hg mv dir/b e
23 $ hg ci -me -d '5 0'
23 $ hg ci -me -d '5 0'
24
24
25 $ hg log a
25 $ hg log a
26 changeset: 0:8580ff50825a
26 changeset: 0:8580ff50825a
27 user: test
27 user: test
28 date: Thu Jan 01 00:00:01 1970 +0000
28 date: Thu Jan 01 00:00:01 1970 +0000
29 summary: a
29 summary: a
30
30
31
31
32 -f, directory
32 -f, directory
33
33
34 $ hg log -f dir
34 $ hg log -f dir
35 abort: cannot follow nonexistent file: "dir"
35 abort: cannot follow nonexistent file: "dir"
36 [255]
36 [255]
37
37
38 -f, but no args
38 -f, but no args
39
39
40 $ hg log -f
40 $ hg log -f
41 changeset: 4:66c1345dc4f9
41 changeset: 4:66c1345dc4f9
42 tag: tip
42 tag: tip
43 user: test
43 user: test
44 date: Thu Jan 01 00:00:05 1970 +0000
44 date: Thu Jan 01 00:00:05 1970 +0000
45 summary: e
45 summary: e
46
46
47 changeset: 3:7c6c671bb7cc
47 changeset: 3:7c6c671bb7cc
48 user: test
48 user: test
49 date: Thu Jan 01 00:00:04 1970 +0000
49 date: Thu Jan 01 00:00:04 1970 +0000
50 summary: d
50 summary: d
51
51
52 changeset: 2:41dd4284081e
52 changeset: 2:41dd4284081e
53 user: test
53 user: test
54 date: Thu Jan 01 00:00:03 1970 +0000
54 date: Thu Jan 01 00:00:03 1970 +0000
55 summary: c
55 summary: c
56
56
57 changeset: 1:784de7cef101
57 changeset: 1:784de7cef101
58 user: test
58 user: test
59 date: Thu Jan 01 00:00:02 1970 +0000
59 date: Thu Jan 01 00:00:02 1970 +0000
60 summary: b
60 summary: b
61
61
62 changeset: 0:8580ff50825a
62 changeset: 0:8580ff50825a
63 user: test
63 user: test
64 date: Thu Jan 01 00:00:01 1970 +0000
64 date: Thu Jan 01 00:00:01 1970 +0000
65 summary: a
65 summary: a
66
66
67
67
68 one rename
68 one rename
69
69
70 $ hg log -vf a
70 $ hg log -vf a
71 changeset: 0:8580ff50825a
71 changeset: 0:8580ff50825a
72 user: test
72 user: test
73 date: Thu Jan 01 00:00:01 1970 +0000
73 date: Thu Jan 01 00:00:01 1970 +0000
74 files: a
74 files: a
75 description:
75 description:
76 a
76 a
77
77
78
78
79
79
80 many renames
80 many renames
81
81
82 $ hg log -vf e
82 $ hg log -vf e
83 changeset: 4:66c1345dc4f9
83 changeset: 4:66c1345dc4f9
84 tag: tip
84 tag: tip
85 user: test
85 user: test
86 date: Thu Jan 01 00:00:05 1970 +0000
86 date: Thu Jan 01 00:00:05 1970 +0000
87 files: dir/b e
87 files: dir/b e
88 description:
88 description:
89 e
89 e
90
90
91
91
92 changeset: 2:41dd4284081e
92 changeset: 2:41dd4284081e
93 user: test
93 user: test
94 date: Thu Jan 01 00:00:03 1970 +0000
94 date: Thu Jan 01 00:00:03 1970 +0000
95 files: b dir/b
95 files: b dir/b
96 description:
96 description:
97 c
97 c
98
98
99
99
100 changeset: 1:784de7cef101
100 changeset: 1:784de7cef101
101 user: test
101 user: test
102 date: Thu Jan 01 00:00:02 1970 +0000
102 date: Thu Jan 01 00:00:02 1970 +0000
103 files: b
103 files: b
104 description:
104 description:
105 b
105 b
106
106
107
107
108 changeset: 0:8580ff50825a
108 changeset: 0:8580ff50825a
109 user: test
109 user: test
110 date: Thu Jan 01 00:00:01 1970 +0000
110 date: Thu Jan 01 00:00:01 1970 +0000
111 files: a
111 files: a
112 description:
112 description:
113 a
113 a
114
114
115
115
116
116
117
117
118 log -pf dir/b
118 log -pf dir/b
119
119
120 $ hg log -pf dir/b
120 $ hg log -pf dir/b
121 changeset: 2:41dd4284081e
121 changeset: 2:41dd4284081e
122 user: test
122 user: test
123 date: Thu Jan 01 00:00:03 1970 +0000
123 date: Thu Jan 01 00:00:03 1970 +0000
124 summary: c
124 summary: c
125
125
126 diff -r 784de7cef101 -r 41dd4284081e dir/b
126 diff -r 784de7cef101 -r 41dd4284081e dir/b
127 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
127 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
128 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
129 @@ -0,0 +1,1 @@
129 @@ -0,0 +1,1 @@
130 +a
130 +a
131
131
132 changeset: 1:784de7cef101
132 changeset: 1:784de7cef101
133 user: test
133 user: test
134 date: Thu Jan 01 00:00:02 1970 +0000
134 date: Thu Jan 01 00:00:02 1970 +0000
135 summary: b
135 summary: b
136
136
137 diff -r 8580ff50825a -r 784de7cef101 b
137 diff -r 8580ff50825a -r 784de7cef101 b
138 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
138 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
139 +++ b/b Thu Jan 01 00:00:02 1970 +0000
139 +++ b/b Thu Jan 01 00:00:02 1970 +0000
140 @@ -0,0 +1,1 @@
140 @@ -0,0 +1,1 @@
141 +a
141 +a
142
142
143 changeset: 0:8580ff50825a
143 changeset: 0:8580ff50825a
144 user: test
144 user: test
145 date: Thu Jan 01 00:00:01 1970 +0000
145 date: Thu Jan 01 00:00:01 1970 +0000
146 summary: a
146 summary: a
147
147
148 diff -r 000000000000 -r 8580ff50825a a
148 diff -r 000000000000 -r 8580ff50825a a
149 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
149 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150 +++ b/a Thu Jan 01 00:00:01 1970 +0000
150 +++ b/a Thu Jan 01 00:00:01 1970 +0000
151 @@ -0,0 +1,1 @@
151 @@ -0,0 +1,1 @@
152 +a
152 +a
153
153
154
154
155 log -vf dir/b
155 log -vf dir/b
156
156
157 $ hg log -vf dir/b
157 $ hg log -vf dir/b
158 changeset: 2:41dd4284081e
158 changeset: 2:41dd4284081e
159 user: test
159 user: test
160 date: Thu Jan 01 00:00:03 1970 +0000
160 date: Thu Jan 01 00:00:03 1970 +0000
161 files: b dir/b
161 files: b dir/b
162 description:
162 description:
163 c
163 c
164
164
165
165
166 changeset: 1:784de7cef101
166 changeset: 1:784de7cef101
167 user: test
167 user: test
168 date: Thu Jan 01 00:00:02 1970 +0000
168 date: Thu Jan 01 00:00:02 1970 +0000
169 files: b
169 files: b
170 description:
170 description:
171 b
171 b
172
172
173
173
174 changeset: 0:8580ff50825a
174 changeset: 0:8580ff50825a
175 user: test
175 user: test
176 date: Thu Jan 01 00:00:01 1970 +0000
176 date: Thu Jan 01 00:00:01 1970 +0000
177 files: a
177 files: a
178 description:
178 description:
179 a
179 a
180
180
181
181
182
182
183
183
184 log copies with --copies
184 log copies with --copies
185
185
186 $ hg log -vC --template '{rev} {file_copies}\n'
186 $ hg log -vC --template '{rev} {file_copies}\n'
187 4 e (dir/b)
187 4 e (dir/b)
188 3 b (a)
188 3 b (a)
189 2 dir/b (b)
189 2 dir/b (b)
190 1 b (a)
190 1 b (a)
191 0
191 0
192
192
193 log copies switch without --copies, with old filecopy template
193 log copies switch without --copies, with old filecopy template
194
194
195 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
195 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
196 4
196 4
197 3
197 3
198 2
198 2
199 1
199 1
200 0
200 0
201
201
202 log copies switch with --copies
202 log copies switch with --copies
203
203
204 $ hg log -vC --template '{rev} {file_copies_switch}\n'
204 $ hg log -vC --template '{rev} {file_copies_switch}\n'
205 4 e (dir/b)
205 4 e (dir/b)
206 3 b (a)
206 3 b (a)
207 2 dir/b (b)
207 2 dir/b (b)
208 1 b (a)
208 1 b (a)
209 0
209 0
210
210
211
211
212 log copies with hardcoded style and with --style=default
212 log copies with hardcoded style and with --style=default
213
213
214 $ hg log -vC -r4
214 $ hg log -vC -r4
215 changeset: 4:66c1345dc4f9
215 changeset: 4:66c1345dc4f9
216 tag: tip
216 tag: tip
217 user: test
217 user: test
218 date: Thu Jan 01 00:00:05 1970 +0000
218 date: Thu Jan 01 00:00:05 1970 +0000
219 files: dir/b e
219 files: dir/b e
220 copies: e (dir/b)
220 copies: e (dir/b)
221 description:
221 description:
222 e
222 e
223
223
224
224
225 $ hg log -vC -r4 --style=default
225 $ hg log -vC -r4 --style=default
226 changeset: 4:66c1345dc4f9
226 changeset: 4:66c1345dc4f9
227 tag: tip
227 tag: tip
228 user: test
228 user: test
229 date: Thu Jan 01 00:00:05 1970 +0000
229 date: Thu Jan 01 00:00:05 1970 +0000
230 files: dir/b e
230 files: dir/b e
231 copies: e (dir/b)
231 copies: e (dir/b)
232 description:
232 description:
233 e
233 e
234
234
235
235
236
236
237
237
238 log copies, non-linear manifest
238 log copies, non-linear manifest
239
239
240 $ hg up -C 3
240 $ hg up -C 3
241 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
241 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
242 $ hg mv dir/b e
242 $ hg mv dir/b e
243 $ echo foo > foo
243 $ echo foo > foo
244 $ hg ci -Ame2 -d '6 0'
244 $ hg ci -Ame2 -d '6 0'
245 adding foo
245 adding foo
246 created new head
246 created new head
247 $ hg log -v --template '{rev} {file_copies}\n' -r 5
247 $ hg log -v --template '{rev} {file_copies}\n' -r 5
248 5 e (dir/b)
248 5 e (dir/b)
249
249
250
250
251 log copies, execute bit set
251 log copies, execute bit set
252
252
253 $ chmod +x e
253 $ chmod +x e
254 $ hg ci -me3 -d '7 0'
254 $ hg ci -me3 -d '7 0'
255 $ hg log -v --template '{rev} {file_copies}\n' -r 6
255 $ hg log -v --template '{rev} {file_copies}\n' -r 6
256 6
256 6
257
257
258
258
259 log -p d
259 log -p d
260
260
261 $ hg log -pv d
261 $ hg log -pv d
262 changeset: 3:7c6c671bb7cc
262 changeset: 3:7c6c671bb7cc
263 user: test
263 user: test
264 date: Thu Jan 01 00:00:04 1970 +0000
264 date: Thu Jan 01 00:00:04 1970 +0000
265 files: a b d
265 files: a b d
266 description:
266 description:
267 d
267 d
268
268
269
269
270 diff -r 41dd4284081e -r 7c6c671bb7cc d
270 diff -r 41dd4284081e -r 7c6c671bb7cc d
271 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
271 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
272 +++ b/d Thu Jan 01 00:00:04 1970 +0000
272 +++ b/d Thu Jan 01 00:00:04 1970 +0000
273 @@ -0,0 +1,1 @@
273 @@ -0,0 +1,1 @@
274 +a
274 +a
275
275
276
276
277
277
278 log --removed file
278 log --removed file
279
279
280 $ hg log --removed -v a
280 $ hg log --removed -v a
281 changeset: 3:7c6c671bb7cc
281 changeset: 3:7c6c671bb7cc
282 user: test
282 user: test
283 date: Thu Jan 01 00:00:04 1970 +0000
283 date: Thu Jan 01 00:00:04 1970 +0000
284 files: a b d
284 files: a b d
285 description:
285 description:
286 d
286 d
287
287
288
288
289 changeset: 0:8580ff50825a
289 changeset: 0:8580ff50825a
290 user: test
290 user: test
291 date: Thu Jan 01 00:00:01 1970 +0000
291 date: Thu Jan 01 00:00:01 1970 +0000
292 files: a
292 files: a
293 description:
293 description:
294 a
294 a
295
295
296
296
297
297
298 log --removed revrange file
298 log --removed revrange file
299
299
300 $ hg log --removed -v -r0:2 a
300 $ hg log --removed -v -r0:2 a
301 changeset: 0:8580ff50825a
301 changeset: 0:8580ff50825a
302 user: test
302 user: test
303 date: Thu Jan 01 00:00:01 1970 +0000
303 date: Thu Jan 01 00:00:01 1970 +0000
304 files: a
304 files: a
305 description:
305 description:
306 a
306 a
307
307
308
308
309
309
310
310
311 log --follow tests
311 log --follow tests
312
312
313 $ hg init ../follow
313 $ hg init ../follow
314 $ cd ../follow
314 $ cd ../follow
315
315
316 $ echo base > base
316 $ echo base > base
317 $ hg ci -Ambase -d '1 0'
317 $ hg ci -Ambase -d '1 0'
318 adding base
318 adding base
319
319
320 $ echo r1 >> base
320 $ echo r1 >> base
321 $ hg ci -Amr1 -d '1 0'
321 $ hg ci -Amr1 -d '1 0'
322 $ echo r2 >> base
322 $ echo r2 >> base
323 $ hg ci -Amr2 -d '1 0'
323 $ hg ci -Amr2 -d '1 0'
324
324
325 $ hg up -C 1
325 $ hg up -C 1
326 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
327 $ echo b1 > b1
327 $ echo b1 > b1
328 $ hg ci -Amb1 -d '1 0'
328 $ hg ci -Amb1 -d '1 0'
329 adding b1
329 adding b1
330 created new head
330 created new head
331
331
332
332
333 log -f
333 log -f
334
334
335 $ hg log -f
335 $ hg log -f
336 changeset: 3:e62f78d544b4
336 changeset: 3:e62f78d544b4
337 tag: tip
337 tag: tip
338 parent: 1:3d5bf5654eda
338 parent: 1:3d5bf5654eda
339 user: test
339 user: test
340 date: Thu Jan 01 00:00:01 1970 +0000
340 date: Thu Jan 01 00:00:01 1970 +0000
341 summary: b1
341 summary: b1
342
342
343 changeset: 1:3d5bf5654eda
343 changeset: 1:3d5bf5654eda
344 user: test
344 user: test
345 date: Thu Jan 01 00:00:01 1970 +0000
345 date: Thu Jan 01 00:00:01 1970 +0000
346 summary: r1
346 summary: r1
347
347
348 changeset: 0:67e992f2c4f3
348 changeset: 0:67e992f2c4f3
349 user: test
349 user: test
350 date: Thu Jan 01 00:00:01 1970 +0000
350 date: Thu Jan 01 00:00:01 1970 +0000
351 summary: base
351 summary: base
352
352
353
353
354
354
355 log -f -r 1:tip
355 log -f -r 1:tip
356
356
357 $ hg up -C 0
357 $ hg up -C 0
358 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
358 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
359 $ echo b2 > b2
359 $ echo b2 > b2
360 $ hg ci -Amb2 -d '1 0'
360 $ hg ci -Amb2 -d '1 0'
361 adding b2
361 adding b2
362 created new head
362 created new head
363 $ hg log -f -r 1:tip
363 $ hg log -f -r 1:tip
364 changeset: 1:3d5bf5654eda
364 changeset: 1:3d5bf5654eda
365 user: test
365 user: test
366 date: Thu Jan 01 00:00:01 1970 +0000
366 date: Thu Jan 01 00:00:01 1970 +0000
367 summary: r1
367 summary: r1
368
368
369 changeset: 2:60c670bf5b30
369 changeset: 2:60c670bf5b30
370 user: test
370 user: test
371 date: Thu Jan 01 00:00:01 1970 +0000
371 date: Thu Jan 01 00:00:01 1970 +0000
372 summary: r2
372 summary: r2
373
373
374 changeset: 3:e62f78d544b4
374 changeset: 3:e62f78d544b4
375 parent: 1:3d5bf5654eda
375 parent: 1:3d5bf5654eda
376 user: test
376 user: test
377 date: Thu Jan 01 00:00:01 1970 +0000
377 date: Thu Jan 01 00:00:01 1970 +0000
378 summary: b1
378 summary: b1
379
379
380
380
381
381
382 log -r . with two parents
382 log -r . with two parents
383
383
384 $ hg up -C 3
384 $ hg up -C 3
385 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
385 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
386 $ hg merge tip
386 $ hg merge tip
387 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 (branch merge, don't forget to commit)
388 (branch merge, don't forget to commit)
389 $ hg log -r .
389 $ hg log -r .
390 changeset: 3:e62f78d544b4
390 changeset: 3:e62f78d544b4
391 parent: 1:3d5bf5654eda
391 parent: 1:3d5bf5654eda
392 user: test
392 user: test
393 date: Thu Jan 01 00:00:01 1970 +0000
393 date: Thu Jan 01 00:00:01 1970 +0000
394 summary: b1
394 summary: b1
395
395
396
396
397
397
398 log -r . with one parent
398 log -r . with one parent
399
399
400 $ hg ci -mm12 -d '1 0'
400 $ hg ci -mm12 -d '1 0'
401 $ hg log -r .
401 $ hg log -r .
402 changeset: 5:302e9dd6890d
402 changeset: 5:302e9dd6890d
403 tag: tip
403 tag: tip
404 parent: 3:e62f78d544b4
404 parent: 3:e62f78d544b4
405 parent: 4:ddb82e70d1a1
405 parent: 4:ddb82e70d1a1
406 user: test
406 user: test
407 date: Thu Jan 01 00:00:01 1970 +0000
407 date: Thu Jan 01 00:00:01 1970 +0000
408 summary: m12
408 summary: m12
409
409
410
410
411 $ echo postm >> b1
411 $ echo postm >> b1
412 $ hg ci -Amb1.1 -d'1 0'
412 $ hg ci -Amb1.1 -d'1 0'
413
413
414
414
415 log --follow-first
415 log --follow-first
416
416
417 $ hg log --follow-first
417 $ hg log --follow-first
418 changeset: 6:2404bbcab562
418 changeset: 6:2404bbcab562
419 tag: tip
419 tag: tip
420 user: test
420 user: test
421 date: Thu Jan 01 00:00:01 1970 +0000
421 date: Thu Jan 01 00:00:01 1970 +0000
422 summary: b1.1
422 summary: b1.1
423
423
424 changeset: 5:302e9dd6890d
424 changeset: 5:302e9dd6890d
425 parent: 3:e62f78d544b4
425 parent: 3:e62f78d544b4
426 parent: 4:ddb82e70d1a1
426 parent: 4:ddb82e70d1a1
427 user: test
427 user: test
428 date: Thu Jan 01 00:00:01 1970 +0000
428 date: Thu Jan 01 00:00:01 1970 +0000
429 summary: m12
429 summary: m12
430
430
431 changeset: 3:e62f78d544b4
431 changeset: 3:e62f78d544b4
432 parent: 1:3d5bf5654eda
432 parent: 1:3d5bf5654eda
433 user: test
433 user: test
434 date: Thu Jan 01 00:00:01 1970 +0000
434 date: Thu Jan 01 00:00:01 1970 +0000
435 summary: b1
435 summary: b1
436
436
437 changeset: 1:3d5bf5654eda
437 changeset: 1:3d5bf5654eda
438 user: test
438 user: test
439 date: Thu Jan 01 00:00:01 1970 +0000
439 date: Thu Jan 01 00:00:01 1970 +0000
440 summary: r1
440 summary: r1
441
441
442 changeset: 0:67e992f2c4f3
442 changeset: 0:67e992f2c4f3
443 user: test
443 user: test
444 date: Thu Jan 01 00:00:01 1970 +0000
444 date: Thu Jan 01 00:00:01 1970 +0000
445 summary: base
445 summary: base
446
446
447
447
448
448
449 log -P 2
449 log -P 2
450
450
451 $ hg log -P 2
451 $ hg log -P 2
452 changeset: 6:2404bbcab562
452 changeset: 6:2404bbcab562
453 tag: tip
453 tag: tip
454 user: test
454 user: test
455 date: Thu Jan 01 00:00:01 1970 +0000
455 date: Thu Jan 01 00:00:01 1970 +0000
456 summary: b1.1
456 summary: b1.1
457
457
458 changeset: 5:302e9dd6890d
458 changeset: 5:302e9dd6890d
459 parent: 3:e62f78d544b4
459 parent: 3:e62f78d544b4
460 parent: 4:ddb82e70d1a1
460 parent: 4:ddb82e70d1a1
461 user: test
461 user: test
462 date: Thu Jan 01 00:00:01 1970 +0000
462 date: Thu Jan 01 00:00:01 1970 +0000
463 summary: m12
463 summary: m12
464
464
465 changeset: 4:ddb82e70d1a1
465 changeset: 4:ddb82e70d1a1
466 parent: 0:67e992f2c4f3
466 parent: 0:67e992f2c4f3
467 user: test
467 user: test
468 date: Thu Jan 01 00:00:01 1970 +0000
468 date: Thu Jan 01 00:00:01 1970 +0000
469 summary: b2
469 summary: b2
470
470
471 changeset: 3:e62f78d544b4
471 changeset: 3:e62f78d544b4
472 parent: 1:3d5bf5654eda
472 parent: 1:3d5bf5654eda
473 user: test
473 user: test
474 date: Thu Jan 01 00:00:01 1970 +0000
474 date: Thu Jan 01 00:00:01 1970 +0000
475 summary: b1
475 summary: b1
476
476
477
477
478
478
479 log -r tip -p --git
479 log -r tip -p --git
480
480
481 $ hg log -r tip -p --git
481 $ hg log -r tip -p --git
482 changeset: 6:2404bbcab562
482 changeset: 6:2404bbcab562
483 tag: tip
483 tag: tip
484 user: test
484 user: test
485 date: Thu Jan 01 00:00:01 1970 +0000
485 date: Thu Jan 01 00:00:01 1970 +0000
486 summary: b1.1
486 summary: b1.1
487
487
488 diff --git a/b1 b/b1
488 diff --git a/b1 b/b1
489 --- a/b1
489 --- a/b1
490 +++ b/b1
490 +++ b/b1
491 @@ -1,1 +1,2 @@
491 @@ -1,1 +1,2 @@
492 b1
492 b1
493 +postm
493 +postm
494
494
495
495
496
496
497 log -r ""
497 log -r ""
498
498
499 $ hg log -r ''
499 $ hg log -r ''
500 hg: parse error: empty query
500 hg: parse error: empty query
501 [255]
501 [255]
502
502
503 log -r <some unknown node id>
503 log -r <some unknown node id>
504
504
505 $ hg log -r 1000000000000000000000000000000000000000
505 $ hg log -r 1000000000000000000000000000000000000000
506 abort: unknown revision '1000000000000000000000000000000000000000'!
506 abort: unknown revision '1000000000000000000000000000000000000000'!
507 [255]
507 [255]
508
508
509 log -k r1
509 log -k r1
510
510
511 $ hg log -k r1
511 $ hg log -k r1
512 changeset: 1:3d5bf5654eda
512 changeset: 1:3d5bf5654eda
513 user: test
513 user: test
514 date: Thu Jan 01 00:00:01 1970 +0000
514 date: Thu Jan 01 00:00:01 1970 +0000
515 summary: r1
515 summary: r1
516
516
517 log -d " " (whitespaces only)
517 log -d " " (whitespaces only)
518
518
519 $ hg log -d " "
519 $ hg log -d " "
520 abort: dates cannot consist entirely of whitespace
520 abort: dates cannot consist entirely of whitespace
521 [255]
521 [255]
522
522
523 log -d -1
523 log -d -1
524
524
525 $ hg log -d -1
525 $ hg log -d -1
526
526
527 log -d ">"
527 log -d ">"
528
528
529 $ hg log -d ">"
529 $ hg log -d ">"
530 abort: invalid day spec, use '>DATE'
530 abort: invalid day spec, use '>DATE'
531 [255]
531 [255]
532
532
533 log -d "<"
533 log -d "<"
534
534
535 $ hg log -d "<"
535 $ hg log -d "<"
536 abort: invalid day spec, use '<DATE'
536 abort: invalid day spec, use '<DATE'
537 [255]
537 [255]
538
538
539 Negative ranges
539 Negative ranges
540 $ hg log -d "--2"
540 $ hg log -d "--2"
541 abort: -2 must be nonnegative (see 'hg help dates')
541 abort: -2 must be nonnegative (see 'hg help dates')
542 [255]
542 [255]
543
543
544
544
545 log -p -l2 --color=always
545 log -p -l2 --color=always
546
546
547 $ hg --config extensions.color= --config color.mode=ansi \
547 $ hg --config extensions.color= --config color.mode=ansi \
548 > log -p -l2 --color=always
548 > log -p -l2 --color=always
549 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
549 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
550 tag: tip
550 tag: tip
551 user: test
551 user: test
552 date: Thu Jan 01 00:00:01 1970 +0000
552 date: Thu Jan 01 00:00:01 1970 +0000
553 summary: b1.1
553 summary: b1.1
554
554
555 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
555 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
556 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
556 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
557 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
557 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
558 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
558 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
559 b1
559 b1
560 \x1b[0;32m+postm\x1b[0m (esc)
560 \x1b[0;32m+postm\x1b[0m (esc)
561
561
562 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
562 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
563 parent: 3:e62f78d544b4
563 parent: 3:e62f78d544b4
564 parent: 4:ddb82e70d1a1
564 parent: 4:ddb82e70d1a1
565 user: test
565 user: test
566 date: Thu Jan 01 00:00:01 1970 +0000
566 date: Thu Jan 01 00:00:01 1970 +0000
567 summary: m12
567 summary: m12
568
568
569 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
569 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
570 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
570 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
571 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
571 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
572 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
572 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
573 \x1b[0;32m+b2\x1b[0m (esc)
573 \x1b[0;32m+b2\x1b[0m (esc)
574
574
575
575
576
576
577 log -r tip --stat
577 log -r tip --stat
578
578
579 $ hg log -r tip --stat
579 $ hg log -r tip --stat
580 changeset: 6:2404bbcab562
580 changeset: 6:2404bbcab562
581 tag: tip
581 tag: tip
582 user: test
582 user: test
583 date: Thu Jan 01 00:00:01 1970 +0000
583 date: Thu Jan 01 00:00:01 1970 +0000
584 summary: b1.1
584 summary: b1.1
585
585
586 b1 | 1 +
586 b1 | 1 +
587 1 files changed, 1 insertions(+), 0 deletions(-)
587 1 files changed, 1 insertions(+), 0 deletions(-)
588
588
589
589
590 $ cd ..
590 $ cd ..
591
591
592 $ hg init usertest
592 $ hg init usertest
593 $ cd usertest
593 $ cd usertest
594
594
595 $ echo a > a
595 $ echo a > a
596 $ hg ci -A -m "a" -u "User One <user1@example.org>"
596 $ hg ci -A -m "a" -u "User One <user1@example.org>"
597 adding a
597 adding a
598 $ echo b > b
598 $ echo b > b
599 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
599 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
600 adding b
600 adding b
601
601
602 $ hg log -u "User One <user1@example.org>"
602 $ hg log -u "User One <user1@example.org>"
603 changeset: 0:29a4c94f1924
603 changeset: 0:29a4c94f1924
604 user: User One <user1@example.org>
604 user: User One <user1@example.org>
605 date: Thu Jan 01 00:00:00 1970 +0000
605 date: Thu Jan 01 00:00:00 1970 +0000
606 summary: a
606 summary: a
607
607
608 $ hg log -u "user1" -u "user2"
608 $ hg log -u "user1" -u "user2"
609 changeset: 1:e834b5e69c0e
609 changeset: 1:e834b5e69c0e
610 tag: tip
610 tag: tip
611 user: User Two <user2@example.org>
611 user: User Two <user2@example.org>
612 date: Thu Jan 01 00:00:00 1970 +0000
612 date: Thu Jan 01 00:00:00 1970 +0000
613 summary: b
613 summary: b
614
614
615 changeset: 0:29a4c94f1924
615 changeset: 0:29a4c94f1924
616 user: User One <user1@example.org>
616 user: User One <user1@example.org>
617 date: Thu Jan 01 00:00:00 1970 +0000
617 date: Thu Jan 01 00:00:00 1970 +0000
618 summary: a
618 summary: a
619
619
620 $ hg log -u "user3"
620 $ hg log -u "user3"
621
621
622 $ cd ..
622 $ cd ..
623
623
624 $ hg init branches
624 $ hg init branches
625 $ cd branches
625 $ cd branches
626
626
627 $ echo a > a
627 $ echo a > a
628 $ hg ci -A -m "commit on default"
628 $ hg ci -A -m "commit on default"
629 adding a
629 adding a
630 $ hg branch test
630 $ hg branch test
631 marked working directory as branch test
631 marked working directory as branch test
632 (branches are permanent and global, did you want a bookmark?)
632 $ echo b > b
633 $ echo b > b
633 $ hg ci -A -m "commit on test"
634 $ hg ci -A -m "commit on test"
634 adding b
635 adding b
635
636
636 $ hg up default
637 $ hg up default
637 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
638 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
638 $ echo c > c
639 $ echo c > c
639 $ hg ci -A -m "commit on default"
640 $ hg ci -A -m "commit on default"
640 adding c
641 adding c
641 $ hg up test
642 $ hg up test
642 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
643 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
643 $ echo c > c
644 $ echo c > c
644 $ hg ci -A -m "commit on test"
645 $ hg ci -A -m "commit on test"
645 adding c
646 adding c
646
647
647
648
648 log -b default
649 log -b default
649
650
650 $ hg log -b default
651 $ hg log -b default
651 changeset: 2:c3a4f03cc9a7
652 changeset: 2:c3a4f03cc9a7
652 parent: 0:24427303d56f
653 parent: 0:24427303d56f
653 user: test
654 user: test
654 date: Thu Jan 01 00:00:00 1970 +0000
655 date: Thu Jan 01 00:00:00 1970 +0000
655 summary: commit on default
656 summary: commit on default
656
657
657 changeset: 0:24427303d56f
658 changeset: 0:24427303d56f
658 user: test
659 user: test
659 date: Thu Jan 01 00:00:00 1970 +0000
660 date: Thu Jan 01 00:00:00 1970 +0000
660 summary: commit on default
661 summary: commit on default
661
662
662
663
663
664
664 log -b test
665 log -b test
665
666
666 $ hg log -b test
667 $ hg log -b test
667 changeset: 3:f5d8de11c2e2
668 changeset: 3:f5d8de11c2e2
668 branch: test
669 branch: test
669 tag: tip
670 tag: tip
670 parent: 1:d32277701ccb
671 parent: 1:d32277701ccb
671 user: test
672 user: test
672 date: Thu Jan 01 00:00:00 1970 +0000
673 date: Thu Jan 01 00:00:00 1970 +0000
673 summary: commit on test
674 summary: commit on test
674
675
675 changeset: 1:d32277701ccb
676 changeset: 1:d32277701ccb
676 branch: test
677 branch: test
677 user: test
678 user: test
678 date: Thu Jan 01 00:00:00 1970 +0000
679 date: Thu Jan 01 00:00:00 1970 +0000
679 summary: commit on test
680 summary: commit on test
680
681
681
682
682
683
683 log -b dummy
684 log -b dummy
684
685
685 $ hg log -b dummy
686 $ hg log -b dummy
686 abort: unknown revision 'dummy'!
687 abort: unknown revision 'dummy'!
687 [255]
688 [255]
688
689
689
690
690 log -b .
691 log -b .
691
692
692 $ hg log -b .
693 $ hg log -b .
693 changeset: 3:f5d8de11c2e2
694 changeset: 3:f5d8de11c2e2
694 branch: test
695 branch: test
695 tag: tip
696 tag: tip
696 parent: 1:d32277701ccb
697 parent: 1:d32277701ccb
697 user: test
698 user: test
698 date: Thu Jan 01 00:00:00 1970 +0000
699 date: Thu Jan 01 00:00:00 1970 +0000
699 summary: commit on test
700 summary: commit on test
700
701
701 changeset: 1:d32277701ccb
702 changeset: 1:d32277701ccb
702 branch: test
703 branch: test
703 user: test
704 user: test
704 date: Thu Jan 01 00:00:00 1970 +0000
705 date: Thu Jan 01 00:00:00 1970 +0000
705 summary: commit on test
706 summary: commit on test
706
707
707
708
708
709
709 log -b default -b test
710 log -b default -b test
710
711
711 $ hg log -b default -b test
712 $ hg log -b default -b test
712 changeset: 3:f5d8de11c2e2
713 changeset: 3:f5d8de11c2e2
713 branch: test
714 branch: test
714 tag: tip
715 tag: tip
715 parent: 1:d32277701ccb
716 parent: 1:d32277701ccb
716 user: test
717 user: test
717 date: Thu Jan 01 00:00:00 1970 +0000
718 date: Thu Jan 01 00:00:00 1970 +0000
718 summary: commit on test
719 summary: commit on test
719
720
720 changeset: 2:c3a4f03cc9a7
721 changeset: 2:c3a4f03cc9a7
721 parent: 0:24427303d56f
722 parent: 0:24427303d56f
722 user: test
723 user: test
723 date: Thu Jan 01 00:00:00 1970 +0000
724 date: Thu Jan 01 00:00:00 1970 +0000
724 summary: commit on default
725 summary: commit on default
725
726
726 changeset: 1:d32277701ccb
727 changeset: 1:d32277701ccb
727 branch: test
728 branch: test
728 user: test
729 user: test
729 date: Thu Jan 01 00:00:00 1970 +0000
730 date: Thu Jan 01 00:00:00 1970 +0000
730 summary: commit on test
731 summary: commit on test
731
732
732 changeset: 0:24427303d56f
733 changeset: 0:24427303d56f
733 user: test
734 user: test
734 date: Thu Jan 01 00:00:00 1970 +0000
735 date: Thu Jan 01 00:00:00 1970 +0000
735 summary: commit on default
736 summary: commit on default
736
737
737
738
738
739
739 log -b default -b .
740 log -b default -b .
740
741
741 $ hg log -b default -b .
742 $ hg log -b default -b .
742 changeset: 3:f5d8de11c2e2
743 changeset: 3:f5d8de11c2e2
743 branch: test
744 branch: test
744 tag: tip
745 tag: tip
745 parent: 1:d32277701ccb
746 parent: 1:d32277701ccb
746 user: test
747 user: test
747 date: Thu Jan 01 00:00:00 1970 +0000
748 date: Thu Jan 01 00:00:00 1970 +0000
748 summary: commit on test
749 summary: commit on test
749
750
750 changeset: 2:c3a4f03cc9a7
751 changeset: 2:c3a4f03cc9a7
751 parent: 0:24427303d56f
752 parent: 0:24427303d56f
752 user: test
753 user: test
753 date: Thu Jan 01 00:00:00 1970 +0000
754 date: Thu Jan 01 00:00:00 1970 +0000
754 summary: commit on default
755 summary: commit on default
755
756
756 changeset: 1:d32277701ccb
757 changeset: 1:d32277701ccb
757 branch: test
758 branch: test
758 user: test
759 user: test
759 date: Thu Jan 01 00:00:00 1970 +0000
760 date: Thu Jan 01 00:00:00 1970 +0000
760 summary: commit on test
761 summary: commit on test
761
762
762 changeset: 0:24427303d56f
763 changeset: 0:24427303d56f
763 user: test
764 user: test
764 date: Thu Jan 01 00:00:00 1970 +0000
765 date: Thu Jan 01 00:00:00 1970 +0000
765 summary: commit on default
766 summary: commit on default
766
767
767
768
768
769
769 log -b . -b test
770 log -b . -b test
770
771
771 $ hg log -b . -b test
772 $ hg log -b . -b test
772 changeset: 3:f5d8de11c2e2
773 changeset: 3:f5d8de11c2e2
773 branch: test
774 branch: test
774 tag: tip
775 tag: tip
775 parent: 1:d32277701ccb
776 parent: 1:d32277701ccb
776 user: test
777 user: test
777 date: Thu Jan 01 00:00:00 1970 +0000
778 date: Thu Jan 01 00:00:00 1970 +0000
778 summary: commit on test
779 summary: commit on test
779
780
780 changeset: 1:d32277701ccb
781 changeset: 1:d32277701ccb
781 branch: test
782 branch: test
782 user: test
783 user: test
783 date: Thu Jan 01 00:00:00 1970 +0000
784 date: Thu Jan 01 00:00:00 1970 +0000
784 summary: commit on test
785 summary: commit on test
785
786
786
787
787
788
788 log -b 2
789 log -b 2
789
790
790 $ hg log -b 2
791 $ hg log -b 2
791 changeset: 2:c3a4f03cc9a7
792 changeset: 2:c3a4f03cc9a7
792 parent: 0:24427303d56f
793 parent: 0:24427303d56f
793 user: test
794 user: test
794 date: Thu Jan 01 00:00:00 1970 +0000
795 date: Thu Jan 01 00:00:00 1970 +0000
795 summary: commit on default
796 summary: commit on default
796
797
797 changeset: 0:24427303d56f
798 changeset: 0:24427303d56f
798 user: test
799 user: test
799 date: Thu Jan 01 00:00:00 1970 +0000
800 date: Thu Jan 01 00:00:00 1970 +0000
800 summary: commit on default
801 summary: commit on default
801
802
802
803
803
804
804 log -p --cwd dir (in subdir)
805 log -p --cwd dir (in subdir)
805
806
806 $ mkdir dir
807 $ mkdir dir
807 $ hg log -p --cwd dir
808 $ hg log -p --cwd dir
808 changeset: 3:f5d8de11c2e2
809 changeset: 3:f5d8de11c2e2
809 branch: test
810 branch: test
810 tag: tip
811 tag: tip
811 parent: 1:d32277701ccb
812 parent: 1:d32277701ccb
812 user: test
813 user: test
813 date: Thu Jan 01 00:00:00 1970 +0000
814 date: Thu Jan 01 00:00:00 1970 +0000
814 summary: commit on test
815 summary: commit on test
815
816
816 diff -r d32277701ccb -r f5d8de11c2e2 c
817 diff -r d32277701ccb -r f5d8de11c2e2 c
817 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
818 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
818 +++ b/c Thu Jan 01 00:00:00 1970 +0000
819 +++ b/c Thu Jan 01 00:00:00 1970 +0000
819 @@ -0,0 +1,1 @@
820 @@ -0,0 +1,1 @@
820 +c
821 +c
821
822
822 changeset: 2:c3a4f03cc9a7
823 changeset: 2:c3a4f03cc9a7
823 parent: 0:24427303d56f
824 parent: 0:24427303d56f
824 user: test
825 user: test
825 date: Thu Jan 01 00:00:00 1970 +0000
826 date: Thu Jan 01 00:00:00 1970 +0000
826 summary: commit on default
827 summary: commit on default
827
828
828 diff -r 24427303d56f -r c3a4f03cc9a7 c
829 diff -r 24427303d56f -r c3a4f03cc9a7 c
829 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
830 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
830 +++ b/c Thu Jan 01 00:00:00 1970 +0000
831 +++ b/c Thu Jan 01 00:00:00 1970 +0000
831 @@ -0,0 +1,1 @@
832 @@ -0,0 +1,1 @@
832 +c
833 +c
833
834
834 changeset: 1:d32277701ccb
835 changeset: 1:d32277701ccb
835 branch: test
836 branch: test
836 user: test
837 user: test
837 date: Thu Jan 01 00:00:00 1970 +0000
838 date: Thu Jan 01 00:00:00 1970 +0000
838 summary: commit on test
839 summary: commit on test
839
840
840 diff -r 24427303d56f -r d32277701ccb b
841 diff -r 24427303d56f -r d32277701ccb b
841 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
842 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
842 +++ b/b Thu Jan 01 00:00:00 1970 +0000
843 +++ b/b Thu Jan 01 00:00:00 1970 +0000
843 @@ -0,0 +1,1 @@
844 @@ -0,0 +1,1 @@
844 +b
845 +b
845
846
846 changeset: 0:24427303d56f
847 changeset: 0:24427303d56f
847 user: test
848 user: test
848 date: Thu Jan 01 00:00:00 1970 +0000
849 date: Thu Jan 01 00:00:00 1970 +0000
849 summary: commit on default
850 summary: commit on default
850
851
851 diff -r 000000000000 -r 24427303d56f a
852 diff -r 000000000000 -r 24427303d56f a
852 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
853 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
853 +++ b/a Thu Jan 01 00:00:00 1970 +0000
854 +++ b/a Thu Jan 01 00:00:00 1970 +0000
854 @@ -0,0 +1,1 @@
855 @@ -0,0 +1,1 @@
855 +a
856 +a
856
857
857
858
858
859
859 log -p -R repo
860 log -p -R repo
860
861
861 $ cd dir
862 $ cd dir
862 $ hg log -p -R .. ../a
863 $ hg log -p -R .. ../a
863 changeset: 0:24427303d56f
864 changeset: 0:24427303d56f
864 user: test
865 user: test
865 date: Thu Jan 01 00:00:00 1970 +0000
866 date: Thu Jan 01 00:00:00 1970 +0000
866 summary: commit on default
867 summary: commit on default
867
868
868 diff -r 000000000000 -r 24427303d56f a
869 diff -r 000000000000 -r 24427303d56f a
869 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
870 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
870 +++ b/a Thu Jan 01 00:00:00 1970 +0000
871 +++ b/a Thu Jan 01 00:00:00 1970 +0000
871 @@ -0,0 +1,1 @@
872 @@ -0,0 +1,1 @@
872 +a
873 +a
873
874
874
875
875
876
876 $ cd ..
877 $ cd ..
877 $ hg init follow2
878 $ hg init follow2
878 $ cd follow2
879 $ cd follow2
879
880
880
881
881 # Build the following history:
882 # Build the following history:
882 # tip - o - x - o - x - x
883 # tip - o - x - o - x - x
883 # \ /
884 # \ /
884 # o - o - o - x
885 # o - o - o - x
885 # \ /
886 # \ /
886 # o
887 # o
887 #
888 #
888 # Where "o" is a revision containing "foo" and
889 # Where "o" is a revision containing "foo" and
889 # "x" is a revision without "foo"
890 # "x" is a revision without "foo"
890
891
891 $ touch init
892 $ touch init
892 $ hg ci -A -m "init, unrelated"
893 $ hg ci -A -m "init, unrelated"
893 adding init
894 adding init
894 $ echo 'foo' > init
895 $ echo 'foo' > init
895 $ hg ci -m "change, unrelated"
896 $ hg ci -m "change, unrelated"
896 $ echo 'foo' > foo
897 $ echo 'foo' > foo
897 $ hg ci -A -m "add unrelated old foo"
898 $ hg ci -A -m "add unrelated old foo"
898 adding foo
899 adding foo
899 $ hg rm foo
900 $ hg rm foo
900 $ hg ci -m "delete foo, unrelated"
901 $ hg ci -m "delete foo, unrelated"
901 $ echo 'related' > foo
902 $ echo 'related' > foo
902 $ hg ci -A -m "add foo, related"
903 $ hg ci -A -m "add foo, related"
903 adding foo
904 adding foo
904
905
905 $ hg up 0
906 $ hg up 0
906 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
907 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
907 $ touch branch
908 $ touch branch
908 $ hg ci -A -m "first branch, unrelated"
909 $ hg ci -A -m "first branch, unrelated"
909 adding branch
910 adding branch
910 created new head
911 created new head
911 $ touch foo
912 $ touch foo
912 $ hg ci -A -m "create foo, related"
913 $ hg ci -A -m "create foo, related"
913 adding foo
914 adding foo
914 $ echo 'change' > foo
915 $ echo 'change' > foo
915 $ hg ci -m "change foo, related"
916 $ hg ci -m "change foo, related"
916
917
917 $ hg up 6
918 $ hg up 6
918 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
919 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
919 $ echo 'change foo in branch' > foo
920 $ echo 'change foo in branch' > foo
920 $ hg ci -m "change foo in branch, related"
921 $ hg ci -m "change foo in branch, related"
921 created new head
922 created new head
922 $ hg merge 7
923 $ hg merge 7
923 merging foo
924 merging foo
924 warning: conflicts during merge.
925 warning: conflicts during merge.
925 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
926 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
926 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
927 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
927 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
928 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
928 [1]
929 [1]
929 $ echo 'merge 1' > foo
930 $ echo 'merge 1' > foo
930 $ hg resolve -m foo
931 $ hg resolve -m foo
931 $ hg ci -m "First merge, related"
932 $ hg ci -m "First merge, related"
932
933
933 $ hg merge 4
934 $ hg merge 4
934 merging foo
935 merging foo
935 warning: conflicts during merge.
936 warning: conflicts during merge.
936 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
937 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
937 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
938 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
938 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
939 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
939 [1]
940 [1]
940 $ echo 'merge 2' > foo
941 $ echo 'merge 2' > foo
941 $ hg resolve -m foo
942 $ hg resolve -m foo
942 $ hg ci -m "Last merge, related"
943 $ hg ci -m "Last merge, related"
943
944
944 $ hg --config "extensions.graphlog=" glog
945 $ hg --config "extensions.graphlog=" glog
945 @ changeset: 10:4dae8563d2c5
946 @ changeset: 10:4dae8563d2c5
946 |\ tag: tip
947 |\ tag: tip
947 | | parent: 9:7b35701b003e
948 | | parent: 9:7b35701b003e
948 | | parent: 4:88176d361b69
949 | | parent: 4:88176d361b69
949 | | user: test
950 | | user: test
950 | | date: Thu Jan 01 00:00:00 1970 +0000
951 | | date: Thu Jan 01 00:00:00 1970 +0000
951 | | summary: Last merge, related
952 | | summary: Last merge, related
952 | |
953 | |
953 | o changeset: 9:7b35701b003e
954 | o changeset: 9:7b35701b003e
954 | |\ parent: 8:e5416ad8a855
955 | |\ parent: 8:e5416ad8a855
955 | | | parent: 7:87fe3144dcfa
956 | | | parent: 7:87fe3144dcfa
956 | | | user: test
957 | | | user: test
957 | | | date: Thu Jan 01 00:00:00 1970 +0000
958 | | | date: Thu Jan 01 00:00:00 1970 +0000
958 | | | summary: First merge, related
959 | | | summary: First merge, related
959 | | |
960 | | |
960 | | o changeset: 8:e5416ad8a855
961 | | o changeset: 8:e5416ad8a855
961 | | | parent: 6:dc6c325fe5ee
962 | | | parent: 6:dc6c325fe5ee
962 | | | user: test
963 | | | user: test
963 | | | date: Thu Jan 01 00:00:00 1970 +0000
964 | | | date: Thu Jan 01 00:00:00 1970 +0000
964 | | | summary: change foo in branch, related
965 | | | summary: change foo in branch, related
965 | | |
966 | | |
966 | o | changeset: 7:87fe3144dcfa
967 | o | changeset: 7:87fe3144dcfa
967 | |/ user: test
968 | |/ user: test
968 | | date: Thu Jan 01 00:00:00 1970 +0000
969 | | date: Thu Jan 01 00:00:00 1970 +0000
969 | | summary: change foo, related
970 | | summary: change foo, related
970 | |
971 | |
971 | o changeset: 6:dc6c325fe5ee
972 | o changeset: 6:dc6c325fe5ee
972 | | user: test
973 | | user: test
973 | | date: Thu Jan 01 00:00:00 1970 +0000
974 | | date: Thu Jan 01 00:00:00 1970 +0000
974 | | summary: create foo, related
975 | | summary: create foo, related
975 | |
976 | |
976 | o changeset: 5:73db34516eb9
977 | o changeset: 5:73db34516eb9
977 | | parent: 0:e87515fd044a
978 | | parent: 0:e87515fd044a
978 | | user: test
979 | | user: test
979 | | date: Thu Jan 01 00:00:00 1970 +0000
980 | | date: Thu Jan 01 00:00:00 1970 +0000
980 | | summary: first branch, unrelated
981 | | summary: first branch, unrelated
981 | |
982 | |
982 o | changeset: 4:88176d361b69
983 o | changeset: 4:88176d361b69
983 | | user: test
984 | | user: test
984 | | date: Thu Jan 01 00:00:00 1970 +0000
985 | | date: Thu Jan 01 00:00:00 1970 +0000
985 | | summary: add foo, related
986 | | summary: add foo, related
986 | |
987 | |
987 o | changeset: 3:dd78ae4afb56
988 o | changeset: 3:dd78ae4afb56
988 | | user: test
989 | | user: test
989 | | date: Thu Jan 01 00:00:00 1970 +0000
990 | | date: Thu Jan 01 00:00:00 1970 +0000
990 | | summary: delete foo, unrelated
991 | | summary: delete foo, unrelated
991 | |
992 | |
992 o | changeset: 2:c4c64aedf0f7
993 o | changeset: 2:c4c64aedf0f7
993 | | user: test
994 | | user: test
994 | | date: Thu Jan 01 00:00:00 1970 +0000
995 | | date: Thu Jan 01 00:00:00 1970 +0000
995 | | summary: add unrelated old foo
996 | | summary: add unrelated old foo
996 | |
997 | |
997 o | changeset: 1:e5faa7440653
998 o | changeset: 1:e5faa7440653
998 |/ user: test
999 |/ user: test
999 | date: Thu Jan 01 00:00:00 1970 +0000
1000 | date: Thu Jan 01 00:00:00 1970 +0000
1000 | summary: change, unrelated
1001 | summary: change, unrelated
1001 |
1002 |
1002 o changeset: 0:e87515fd044a
1003 o changeset: 0:e87515fd044a
1003 user: test
1004 user: test
1004 date: Thu Jan 01 00:00:00 1970 +0000
1005 date: Thu Jan 01 00:00:00 1970 +0000
1005 summary: init, unrelated
1006 summary: init, unrelated
1006
1007
1007
1008
1008 $ hg --traceback log -f foo
1009 $ hg --traceback log -f foo
1009 changeset: 10:4dae8563d2c5
1010 changeset: 10:4dae8563d2c5
1010 tag: tip
1011 tag: tip
1011 parent: 9:7b35701b003e
1012 parent: 9:7b35701b003e
1012 parent: 4:88176d361b69
1013 parent: 4:88176d361b69
1013 user: test
1014 user: test
1014 date: Thu Jan 01 00:00:00 1970 +0000
1015 date: Thu Jan 01 00:00:00 1970 +0000
1015 summary: Last merge, related
1016 summary: Last merge, related
1016
1017
1017 changeset: 9:7b35701b003e
1018 changeset: 9:7b35701b003e
1018 parent: 8:e5416ad8a855
1019 parent: 8:e5416ad8a855
1019 parent: 7:87fe3144dcfa
1020 parent: 7:87fe3144dcfa
1020 user: test
1021 user: test
1021 date: Thu Jan 01 00:00:00 1970 +0000
1022 date: Thu Jan 01 00:00:00 1970 +0000
1022 summary: First merge, related
1023 summary: First merge, related
1023
1024
1024 changeset: 8:e5416ad8a855
1025 changeset: 8:e5416ad8a855
1025 parent: 6:dc6c325fe5ee
1026 parent: 6:dc6c325fe5ee
1026 user: test
1027 user: test
1027 date: Thu Jan 01 00:00:00 1970 +0000
1028 date: Thu Jan 01 00:00:00 1970 +0000
1028 summary: change foo in branch, related
1029 summary: change foo in branch, related
1029
1030
1030 changeset: 7:87fe3144dcfa
1031 changeset: 7:87fe3144dcfa
1031 user: test
1032 user: test
1032 date: Thu Jan 01 00:00:00 1970 +0000
1033 date: Thu Jan 01 00:00:00 1970 +0000
1033 summary: change foo, related
1034 summary: change foo, related
1034
1035
1035 changeset: 6:dc6c325fe5ee
1036 changeset: 6:dc6c325fe5ee
1036 user: test
1037 user: test
1037 date: Thu Jan 01 00:00:00 1970 +0000
1038 date: Thu Jan 01 00:00:00 1970 +0000
1038 summary: create foo, related
1039 summary: create foo, related
1039
1040
1040 changeset: 4:88176d361b69
1041 changeset: 4:88176d361b69
1041 user: test
1042 user: test
1042 date: Thu Jan 01 00:00:00 1970 +0000
1043 date: Thu Jan 01 00:00:00 1970 +0000
1043 summary: add foo, related
1044 summary: add foo, related
1044
1045
1045
1046
1046 Also check when maxrev < lastrevfilelog
1047 Also check when maxrev < lastrevfilelog
1047
1048
1048 $ hg --traceback log -f -r4 foo
1049 $ hg --traceback log -f -r4 foo
1049 changeset: 4:88176d361b69
1050 changeset: 4:88176d361b69
1050 user: test
1051 user: test
1051 date: Thu Jan 01 00:00:00 1970 +0000
1052 date: Thu Jan 01 00:00:00 1970 +0000
1052 summary: add foo, related
1053 summary: add foo, related
1053
1054
1054
1055
1055 Issue2383: hg log showing _less_ differences than hg diff
1056 Issue2383: hg log showing _less_ differences than hg diff
1056
1057
1057 $ hg init issue2383
1058 $ hg init issue2383
1058 $ cd issue2383
1059 $ cd issue2383
1059
1060
1060 Create a test repo:
1061 Create a test repo:
1061
1062
1062 $ echo a > a
1063 $ echo a > a
1063 $ hg ci -Am0
1064 $ hg ci -Am0
1064 adding a
1065 adding a
1065 $ echo b > b
1066 $ echo b > b
1066 $ hg ci -Am1
1067 $ hg ci -Am1
1067 adding b
1068 adding b
1068 $ hg co 0
1069 $ hg co 0
1069 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1070 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1070 $ echo b > a
1071 $ echo b > a
1071 $ hg ci -m2
1072 $ hg ci -m2
1072 created new head
1073 created new head
1073
1074
1074 Merge:
1075 Merge:
1075
1076
1076 $ hg merge
1077 $ hg merge
1077 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1078 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1078 (branch merge, don't forget to commit)
1079 (branch merge, don't forget to commit)
1079
1080
1080 Make sure there's a file listed in the merge to trigger the bug:
1081 Make sure there's a file listed in the merge to trigger the bug:
1081
1082
1082 $ echo c > a
1083 $ echo c > a
1083 $ hg ci -m3
1084 $ hg ci -m3
1084
1085
1085 Two files shown here in diff:
1086 Two files shown here in diff:
1086
1087
1087 $ hg diff --rev 2:3
1088 $ hg diff --rev 2:3
1088 diff -r b09be438c43a -r 8e07aafe1edc a
1089 diff -r b09be438c43a -r 8e07aafe1edc a
1089 --- a/a Thu Jan 01 00:00:00 1970 +0000
1090 --- a/a Thu Jan 01 00:00:00 1970 +0000
1090 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1091 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1091 @@ -1,1 +1,1 @@
1092 @@ -1,1 +1,1 @@
1092 -b
1093 -b
1093 +c
1094 +c
1094 diff -r b09be438c43a -r 8e07aafe1edc b
1095 diff -r b09be438c43a -r 8e07aafe1edc b
1095 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1096 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1096 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1097 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1097 @@ -0,0 +1,1 @@
1098 @@ -0,0 +1,1 @@
1098 +b
1099 +b
1099
1100
1100 Diff here should be the same:
1101 Diff here should be the same:
1101
1102
1102 $ hg log -vpr 3
1103 $ hg log -vpr 3
1103 changeset: 3:8e07aafe1edc
1104 changeset: 3:8e07aafe1edc
1104 tag: tip
1105 tag: tip
1105 parent: 2:b09be438c43a
1106 parent: 2:b09be438c43a
1106 parent: 1:925d80f479bb
1107 parent: 1:925d80f479bb
1107 user: test
1108 user: test
1108 date: Thu Jan 01 00:00:00 1970 +0000
1109 date: Thu Jan 01 00:00:00 1970 +0000
1109 files: a
1110 files: a
1110 description:
1111 description:
1111 3
1112 3
1112
1113
1113
1114
1114 diff -r b09be438c43a -r 8e07aafe1edc a
1115 diff -r b09be438c43a -r 8e07aafe1edc a
1115 --- a/a Thu Jan 01 00:00:00 1970 +0000
1116 --- a/a Thu Jan 01 00:00:00 1970 +0000
1116 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1117 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1117 @@ -1,1 +1,1 @@
1118 @@ -1,1 +1,1 @@
1118 -b
1119 -b
1119 +c
1120 +c
1120 diff -r b09be438c43a -r 8e07aafe1edc b
1121 diff -r b09be438c43a -r 8e07aafe1edc b
1121 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1122 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1122 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1123 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1123 @@ -0,0 +1,1 @@
1124 @@ -0,0 +1,1 @@
1124 +b
1125 +b
1125
1126
1126 $ cd ..
1127 $ cd ..
1127
1128
1128 'hg log -r rev fn' when last(filelog(fn)) != rev
1129 'hg log -r rev fn' when last(filelog(fn)) != rev
1129
1130
1130 $ hg init simplelog; cd simplelog
1131 $ hg init simplelog; cd simplelog
1131 $ echo f > a
1132 $ echo f > a
1132 $ hg ci -Am'a' -d '0 0'
1133 $ hg ci -Am'a' -d '0 0'
1133 adding a
1134 adding a
1134 $ echo f >> a
1135 $ echo f >> a
1135 $ hg ci -Am'a bis' -d '1 0'
1136 $ hg ci -Am'a bis' -d '1 0'
1136
1137
1137 $ hg log -r0 a
1138 $ hg log -r0 a
1138 changeset: 0:9f758d63dcde
1139 changeset: 0:9f758d63dcde
1139 user: test
1140 user: test
1140 date: Thu Jan 01 00:00:00 1970 +0000
1141 date: Thu Jan 01 00:00:00 1970 +0000
1141 summary: a
1142 summary: a
1142
1143
1143 $ cat > $HGTMP/testhidden.py << EOF
1144 $ cat > $HGTMP/testhidden.py << EOF
1144 > def reposetup(ui, repo):
1145 > def reposetup(ui, repo):
1145 > for line in repo.opener('hidden'):
1146 > for line in repo.opener('hidden'):
1146 > ctx = repo[line.strip()]
1147 > ctx = repo[line.strip()]
1147 > repo.changelog.hiddenrevs.add(ctx.rev())
1148 > repo.changelog.hiddenrevs.add(ctx.rev())
1148 > EOF
1149 > EOF
1149 $ echo '[extensions]' >> $HGRCPATH
1150 $ echo '[extensions]' >> $HGRCPATH
1150 $ echo "hidden=$HGTMP/testhidden.py" >> $HGRCPATH
1151 $ echo "hidden=$HGTMP/testhidden.py" >> $HGRCPATH
1151 $ touch .hg/hidden
1152 $ touch .hg/hidden
1152 $ hg log --template='{rev}:{node}\n'
1153 $ hg log --template='{rev}:{node}\n'
1153 1:a765632148dc55d38c35c4f247c618701886cb2f
1154 1:a765632148dc55d38c35c4f247c618701886cb2f
1154 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1155 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1155 $ echo a765632148dc55d38c35c4f247c618701886cb2f > .hg/hidden
1156 $ echo a765632148dc55d38c35c4f247c618701886cb2f > .hg/hidden
1156 $ hg log --template='{rev}:{node}\n'
1157 $ hg log --template='{rev}:{node}\n'
1157 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1158 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1158 $ hg log --template='{rev}:{node}\n' --hidden
1159 $ hg log --template='{rev}:{node}\n' --hidden
1159 1:a765632148dc55d38c35c4f247c618701886cb2f
1160 1:a765632148dc55d38c35c4f247c618701886cb2f
1160 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1161 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
@@ -1,85 +1,86 b''
1 $ hgcommit() {
1 $ hgcommit() {
2 > hg commit -u user "$@"
2 > hg commit -u user "$@"
3 > }
3 > }
4
4
5 $ hg init clhead
5 $ hg init clhead
6 $ cd clhead
6 $ cd clhead
7
7
8 $ touch foo && hg add && hgcommit -m 'foo'
8 $ touch foo && hg add && hgcommit -m 'foo'
9 adding foo
9 adding foo
10 $ touch bar && hg add && hgcommit -m 'bar'
10 $ touch bar && hg add && hgcommit -m 'bar'
11 adding bar
11 adding bar
12 $ touch baz && hg add && hgcommit -m 'baz'
12 $ touch baz && hg add && hgcommit -m 'baz'
13 adding baz
13 adding baz
14
14
15 $ echo "flub" > foo
15 $ echo "flub" > foo
16 $ hgcommit -m "flub"
16 $ hgcommit -m "flub"
17 $ echo "nub" > foo
17 $ echo "nub" > foo
18 $ hgcommit -m "nub"
18 $ hgcommit -m "nub"
19
19
20 $ hg up -C 2
20 $ hg up -C 2
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22
22
23 $ echo "c1" > c1
23 $ echo "c1" > c1
24 $ hg add c1
24 $ hg add c1
25 $ hgcommit -m "c1"
25 $ hgcommit -m "c1"
26 created new head
26 created new head
27 $ echo "c2" > c1
27 $ echo "c2" > c1
28 $ hgcommit -m "c2"
28 $ hgcommit -m "c2"
29
29
30 $ hg up -C 2
30 $ hg up -C 2
31 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
31 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
32
32
33 $ echo "d1" > d1
33 $ echo "d1" > d1
34 $ hg add d1
34 $ hg add d1
35 $ hgcommit -m "d1"
35 $ hgcommit -m "d1"
36 created new head
36 created new head
37 $ echo "d2" > d1
37 $ echo "d2" > d1
38 $ hgcommit -m "d2"
38 $ hgcommit -m "d2"
39 $ hg tag -l good
39 $ hg tag -l good
40
40
41 fail with three heads
41 fail with three heads
42 $ hg up -C good
42 $ hg up -C good
43 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 $ hg merge
44 $ hg merge
45 abort: branch 'default' has 3 heads - please merge with an explicit rev
45 abort: branch 'default' has 3 heads - please merge with an explicit rev
46 (run 'hg heads .' to see heads)
46 (run 'hg heads .' to see heads)
47 [255]
47 [255]
48
48
49 close one of the heads
49 close one of the heads
50 $ hg up -C 6
50 $ hg up -C 6
51 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
51 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 $ hgcommit -m 'close this head' --close-branch
52 $ hgcommit -m 'close this head' --close-branch
53
53
54 succeed with two open heads
54 succeed with two open heads
55 $ hg up -C good
55 $ hg up -C good
56 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
56 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
57 $ hg up -C good
57 $ hg up -C good
58 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 $ hg merge
59 $ hg merge
60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 (branch merge, don't forget to commit)
61 (branch merge, don't forget to commit)
62 $ hgcommit -m 'merged heads'
62 $ hgcommit -m 'merged heads'
63
63
64 hg update -C 8
64 hg update -C 8
65 $ hg update -C 8
65 $ hg update -C 8
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
67
67
68 hg branch some-branch
68 hg branch some-branch
69 $ hg branch some-branch
69 $ hg branch some-branch
70 marked working directory as branch some-branch
70 marked working directory as branch some-branch
71 (branches are permanent and global, did you want a bookmark?)
71 hg commit
72 hg commit
72 $ hgcommit -m 'started some-branch'
73 $ hgcommit -m 'started some-branch'
73 hg commit --close-branch
74 hg commit --close-branch
74 $ hgcommit --close-branch -m 'closed some-branch'
75 $ hgcommit --close-branch -m 'closed some-branch'
75
76
76 hg update default
77 hg update default
77 $ hg update default
78 $ hg update default
78 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 hg merge some-branch
80 hg merge some-branch
80 $ hg merge some-branch
81 $ hg merge some-branch
81 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 (branch merge, don't forget to commit)
83 (branch merge, don't forget to commit)
83 hg commit (no reopening of some-branch)
84 hg commit (no reopening of some-branch)
84 $ hgcommit -m 'merge with closed branch'
85 $ hgcommit -m 'merge with closed branch'
85
86
@@ -1,110 +1,111 b''
1 $ hg init
1 $ hg init
2 $ echo a > a
2 $ echo a > a
3 $ hg commit -A -ma
3 $ hg commit -A -ma
4 adding a
4 adding a
5
5
6 $ echo b >> a
6 $ echo b >> a
7 $ hg commit -mb
7 $ hg commit -mb
8
8
9 $ echo c >> a
9 $ echo c >> a
10 $ hg commit -mc
10 $ hg commit -mc
11
11
12 $ hg up 1
12 $ hg up 1
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 $ echo d >> a
14 $ echo d >> a
15 $ hg commit -md
15 $ hg commit -md
16 created new head
16 created new head
17
17
18 $ hg up 1
18 $ hg up 1
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ echo e >> a
20 $ echo e >> a
21 $ hg commit -me
21 $ hg commit -me
22 created new head
22 created new head
23
23
24 $ hg up 1
24 $ hg up 1
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
26
26
27 Should fail because not at a head:
27 Should fail because not at a head:
28
28
29 $ hg merge
29 $ hg merge
30 abort: branch 'default' has 3 heads - please merge with an explicit rev
30 abort: branch 'default' has 3 heads - please merge with an explicit rev
31 (run 'hg heads .' to see heads)
31 (run 'hg heads .' to see heads)
32 [255]
32 [255]
33
33
34 $ hg up
34 $ hg up
35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36
36
37 Should fail because > 2 heads:
37 Should fail because > 2 heads:
38
38
39 $ HGMERGE=internal:other; export HGMERGE
39 $ HGMERGE=internal:other; export HGMERGE
40 $ hg merge
40 $ hg merge
41 abort: branch 'default' has 3 heads - please merge with an explicit rev
41 abort: branch 'default' has 3 heads - please merge with an explicit rev
42 (run 'hg heads .' to see heads)
42 (run 'hg heads .' to see heads)
43 [255]
43 [255]
44
44
45 Should succeed:
45 Should succeed:
46
46
47 $ hg merge 2
47 $ hg merge 2
48 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
48 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
49 (branch merge, don't forget to commit)
49 (branch merge, don't forget to commit)
50 $ hg commit -mm1
50 $ hg commit -mm1
51
51
52 Should succeed - 2 heads:
52 Should succeed - 2 heads:
53
53
54 $ hg merge -P
54 $ hg merge -P
55 changeset: 3:ea9ff125ff88
55 changeset: 3:ea9ff125ff88
56 parent: 1:1846eede8b68
56 parent: 1:1846eede8b68
57 user: test
57 user: test
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59 summary: d
59 summary: d
60
60
61 $ hg merge
61 $ hg merge
62 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
62 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
63 (branch merge, don't forget to commit)
63 (branch merge, don't forget to commit)
64 $ hg commit -mm2
64 $ hg commit -mm2
65
65
66 Should fail because at tip:
66 Should fail because at tip:
67
67
68 $ hg merge
68 $ hg merge
69 abort: nothing to merge
69 abort: nothing to merge
70 [255]
70 [255]
71
71
72 $ hg up 0
72 $ hg up 0
73 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
73 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
74
74
75 Should fail because there is only one head:
75 Should fail because there is only one head:
76
76
77 $ hg merge
77 $ hg merge
78 abort: nothing to merge
78 abort: nothing to merge
79 (use 'hg update' instead)
79 (use 'hg update' instead)
80 [255]
80 [255]
81
81
82 $ hg up 3
82 $ hg up 3
83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84
84
85 $ echo f >> a
85 $ echo f >> a
86 $ hg branch foobranch
86 $ hg branch foobranch
87 marked working directory as branch foobranch
87 marked working directory as branch foobranch
88 (branches are permanent and global, did you want a bookmark?)
88 $ hg commit -mf
89 $ hg commit -mf
89
90
90 Should fail because merge with other branch:
91 Should fail because merge with other branch:
91
92
92 $ hg merge
93 $ hg merge
93 abort: branch 'foobranch' has one head - please merge with an explicit rev
94 abort: branch 'foobranch' has one head - please merge with an explicit rev
94 (run 'hg heads' to see all heads)
95 (run 'hg heads' to see all heads)
95 [255]
96 [255]
96
97
97
98
98 Test for issue2043: ensure that 'merge -P' shows ancestors of 6 that
99 Test for issue2043: ensure that 'merge -P' shows ancestors of 6 that
99 are not ancestors of 7, regardless of where their least common
100 are not ancestors of 7, regardless of where their least common
100 ancestor is.
101 ancestor is.
101
102
102 Merge preview not affected by common ancestor:
103 Merge preview not affected by common ancestor:
103
104
104 $ hg up -q 7
105 $ hg up -q 7
105 $ hg merge -q -P 6
106 $ hg merge -q -P 6
106 2:2d95304fed5d
107 2:2d95304fed5d
107 4:f25cbe84d8b3
108 4:f25cbe84d8b3
108 5:a431fabd6039
109 5:a431fabd6039
109 6:e88e33f3bf62
110 6:e88e33f3bf62
110
111
@@ -1,175 +1,177 b''
1 $ echo '[extensions]' >> $HGRCPATH
1 $ echo '[extensions]' >> $HGRCPATH
2 $ echo 'mq =' >> $HGRCPATH
2 $ echo 'mq =' >> $HGRCPATH
3
3
4 $ hg init repo
4 $ hg init repo
5 $ cd repo
5 $ cd repo
6
6
7 $ echo foo > foo
7 $ echo foo > foo
8 $ hg ci -qAm 'add a file'
8 $ hg ci -qAm 'add a file'
9
9
10 $ hg qinit
10 $ hg qinit
11
11
12 $ hg qnew foo
12 $ hg qnew foo
13 $ echo foo >> foo
13 $ echo foo >> foo
14 $ hg qrefresh -m 'append foo'
14 $ hg qrefresh -m 'append foo'
15
15
16 $ hg qnew bar
16 $ hg qnew bar
17 $ echo bar >> foo
17 $ echo bar >> foo
18 $ hg qrefresh -m 'append bar'
18 $ hg qrefresh -m 'append bar'
19
19
20
20
21 try to commit on top of a patch
21 try to commit on top of a patch
22
22
23 $ echo quux >> foo
23 $ echo quux >> foo
24 $ hg ci -m 'append quux'
24 $ hg ci -m 'append quux'
25 abort: cannot commit over an applied mq patch
25 abort: cannot commit over an applied mq patch
26 [255]
26 [255]
27
27
28
28
29 cheat a bit...
29 cheat a bit...
30
30
31 $ mv .hg/patches .hg/patches2
31 $ mv .hg/patches .hg/patches2
32 $ hg ci -m 'append quux'
32 $ hg ci -m 'append quux'
33 $ mv .hg/patches2 .hg/patches
33 $ mv .hg/patches2 .hg/patches
34
34
35
35
36 qpop/qrefresh on the wrong revision
36 qpop/qrefresh on the wrong revision
37
37
38 $ hg qpop
38 $ hg qpop
39 abort: popping would remove a revision not managed by this patch queue
39 abort: popping would remove a revision not managed by this patch queue
40 [255]
40 [255]
41 $ hg qpop -n patches
41 $ hg qpop -n patches
42 using patch queue: $TESTTMP/repo/.hg/patches (glob)
42 using patch queue: $TESTTMP/repo/.hg/patches (glob)
43 abort: popping would remove a revision not managed by this patch queue
43 abort: popping would remove a revision not managed by this patch queue
44 [255]
44 [255]
45 $ hg qrefresh
45 $ hg qrefresh
46 abort: working directory revision is not qtip
46 abort: working directory revision is not qtip
47 [255]
47 [255]
48
48
49 $ hg up -C qtip
49 $ hg up -C qtip
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 $ hg qpop
51 $ hg qpop
52 abort: popping would remove a revision not managed by this patch queue
52 abort: popping would remove a revision not managed by this patch queue
53 [255]
53 [255]
54 $ hg qrefresh
54 $ hg qrefresh
55 abort: cannot refresh a revision with children
55 abort: cannot refresh a revision with children
56 [255]
56 [255]
57 $ hg tip --template '{rev} {desc}\n'
57 $ hg tip --template '{rev} {desc}\n'
58 3 append quux
58 3 append quux
59
59
60
60
61 qpush warning branchheads
61 qpush warning branchheads
62
62
63 $ cd ..
63 $ cd ..
64 $ hg init branchy
64 $ hg init branchy
65 $ cd branchy
65 $ cd branchy
66 $ echo q > q
66 $ echo q > q
67 $ hg add q
67 $ hg add q
68 $ hg qnew -f qp
68 $ hg qnew -f qp
69 $ hg qpop
69 $ hg qpop
70 popping qp
70 popping qp
71 patch queue now empty
71 patch queue now empty
72 $ echo a > a
72 $ echo a > a
73 $ hg ci -Ama
73 $ hg ci -Ama
74 adding a
74 adding a
75 $ hg up null
75 $ hg up null
76 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
76 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
77 $ hg branch b
77 $ hg branch b
78 marked working directory as branch b
78 marked working directory as branch b
79 (branches are permanent and global, did you want a bookmark?)
79 $ echo c > c
80 $ echo c > c
80 $ hg ci -Amc
81 $ hg ci -Amc
81 adding c
82 adding c
82 $ hg merge default
83 $ hg merge default
83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 (branch merge, don't forget to commit)
85 (branch merge, don't forget to commit)
85 $ hg ci -mmerge
86 $ hg ci -mmerge
86 $ hg up default
87 $ hg up default
87 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
88 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
88 $ hg log
89 $ hg log
89 changeset: 2:65309210bf4e
90 changeset: 2:65309210bf4e
90 branch: b
91 branch: b
91 tag: tip
92 tag: tip
92 parent: 1:707adb4c8ae1
93 parent: 1:707adb4c8ae1
93 parent: 0:cb9a9f314b8b
94 parent: 0:cb9a9f314b8b
94 user: test
95 user: test
95 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
96 summary: merge
97 summary: merge
97
98
98 changeset: 1:707adb4c8ae1
99 changeset: 1:707adb4c8ae1
99 branch: b
100 branch: b
100 parent: -1:000000000000
101 parent: -1:000000000000
101 user: test
102 user: test
102 date: Thu Jan 01 00:00:00 1970 +0000
103 date: Thu Jan 01 00:00:00 1970 +0000
103 summary: c
104 summary: c
104
105
105 changeset: 0:cb9a9f314b8b
106 changeset: 0:cb9a9f314b8b
106 user: test
107 user: test
107 date: Thu Jan 01 00:00:00 1970 +0000
108 date: Thu Jan 01 00:00:00 1970 +0000
108 summary: a
109 summary: a
109
110
110 $ hg qpush
111 $ hg qpush
111 applying qp
112 applying qp
112 now at: qp
113 now at: qp
113
114
114 Testing applied patches, push and --force
115 Testing applied patches, push and --force
115
116
116 $ cd ..
117 $ cd ..
117 $ hg init forcepush
118 $ hg init forcepush
118 $ cd forcepush
119 $ cd forcepush
119 $ echo a > a
120 $ echo a > a
120 $ hg ci -Am adda
121 $ hg ci -Am adda
121 adding a
122 adding a
122 $ echo a >> a
123 $ echo a >> a
123 $ hg ci -m changea
124 $ hg ci -m changea
124 $ hg up 0
125 $ hg up 0
125 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 $ hg branch branch
127 $ hg branch branch
127 marked working directory as branch branch
128 marked working directory as branch branch
129 (branches are permanent and global, did you want a bookmark?)
128 $ echo b > b
130 $ echo b > b
129 $ hg ci -Am addb
131 $ hg ci -Am addb
130 adding b
132 adding b
131 $ hg up 0
133 $ hg up 0
132 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
134 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
133 $ hg --cwd .. clone -r 0 forcepush forcepush2
135 $ hg --cwd .. clone -r 0 forcepush forcepush2
134 adding changesets
136 adding changesets
135 adding manifests
137 adding manifests
136 adding file changes
138 adding file changes
137 added 1 changesets with 1 changes to 1 files
139 added 1 changesets with 1 changes to 1 files
138 updating to branch default
140 updating to branch default
139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 $ echo a >> a
142 $ echo a >> a
141 $ hg qnew patch
143 $ hg qnew patch
142
144
143 Pushing applied patch with --rev without --force
145 Pushing applied patch with --rev without --force
144
146
145 $ hg push -r default ../forcepush2
147 $ hg push -r default ../forcepush2
146 pushing to ../forcepush2
148 pushing to ../forcepush2
147 abort: source has mq patches applied
149 abort: source has mq patches applied
148 [255]
150 [255]
149
151
150 Pushing applied patch with branchhash, without --force
152 Pushing applied patch with branchhash, without --force
151
153
152 $ hg push ../forcepush2#default
154 $ hg push ../forcepush2#default
153 pushing to ../forcepush2
155 pushing to ../forcepush2
154 abort: source has mq patches applied
156 abort: source has mq patches applied
155 [255]
157 [255]
156
158
157 Pushing revs excluding applied patch
159 Pushing revs excluding applied patch
158
160
159 $ hg push --new-branch -r branch -r 2 ../forcepush2
161 $ hg push --new-branch -r branch -r 2 ../forcepush2
160 pushing to ../forcepush2
162 pushing to ../forcepush2
161 searching for changes
163 searching for changes
162 adding changesets
164 adding changesets
163 adding manifests
165 adding manifests
164 adding file changes
166 adding file changes
165 added 1 changesets with 1 changes to 1 files
167 added 1 changesets with 1 changes to 1 files
166
168
167 Pushing applied patch with --force
169 Pushing applied patch with --force
168
170
169 $ hg push --force -r default ../forcepush2
171 $ hg push --force -r default ../forcepush2
170 pushing to ../forcepush2
172 pushing to ../forcepush2
171 searching for changes
173 searching for changes
172 adding changesets
174 adding changesets
173 adding manifests
175 adding manifests
174 adding file changes
176 adding file changes
175 added 1 changesets with 1 changes to 1 files (+1 heads)
177 added 1 changesets with 1 changes to 1 files (+1 heads)
@@ -1,322 +1,328 b''
1 $ branchcache=.hg/cache/branchheads
1 $ branchcache=.hg/cache/branchheads
2
2
3 $ hg init t
3 $ hg init t
4 $ cd t
4 $ cd t
5
5
6 $ hg branches
6 $ hg branches
7 $ echo foo > a
7 $ echo foo > a
8 $ hg add a
8 $ hg add a
9 $ hg ci -m "initial"
9 $ hg ci -m "initial"
10 $ hg branch foo
10 $ hg branch foo
11 marked working directory as branch foo
11 marked working directory as branch foo
12 (branches are permanent and global, did you want a bookmark?)
12 $ hg branch
13 $ hg branch
13 foo
14 foo
14 $ hg ci -m "add branch name"
15 $ hg ci -m "add branch name"
15 $ hg branch bar
16 $ hg branch bar
16 marked working directory as branch bar
17 marked working directory as branch bar
18 (branches are permanent and global, did you want a bookmark?)
17 $ hg ci -m "change branch name"
19 $ hg ci -m "change branch name"
18
20
19 Branch shadowing:
21 Branch shadowing:
20
22
21 $ hg branch default
23 $ hg branch default
22 abort: a branch of the same name already exists
24 abort: a branch of the same name already exists
23 (use 'hg update' to switch to it)
25 (use 'hg update' to switch to it)
24 [255]
26 [255]
25
27
26 $ hg branch -f default
28 $ hg branch -f default
27 marked working directory as branch default
29 marked working directory as branch default
30 (branches are permanent and global, did you want a bookmark?)
28
31
29 $ hg ci -m "clear branch name"
32 $ hg ci -m "clear branch name"
30 created new head
33 created new head
31
34
32 There should be only one default branch head
35 There should be only one default branch head
33
36
34 $ hg heads .
37 $ hg heads .
35 changeset: 3:1c28f494dae6
38 changeset: 3:1c28f494dae6
36 tag: tip
39 tag: tip
37 user: test
40 user: test
38 date: Thu Jan 01 00:00:00 1970 +0000
41 date: Thu Jan 01 00:00:00 1970 +0000
39 summary: clear branch name
42 summary: clear branch name
40
43
41
44
42 $ hg co foo
45 $ hg co foo
43 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
46 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 $ hg branch
47 $ hg branch
45 foo
48 foo
46 $ echo bleah > a
49 $ echo bleah > a
47 $ hg ci -m "modify a branch"
50 $ hg ci -m "modify a branch"
48
51
49 $ hg merge default
52 $ hg merge default
50 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
53 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 (branch merge, don't forget to commit)
54 (branch merge, don't forget to commit)
52
55
53 $ hg branch
56 $ hg branch
54 foo
57 foo
55 $ hg ci -m "merge"
58 $ hg ci -m "merge"
56
59
57 $ hg log
60 $ hg log
58 changeset: 5:530046499edf
61 changeset: 5:530046499edf
59 branch: foo
62 branch: foo
60 tag: tip
63 tag: tip
61 parent: 4:adf1a74a7f7b
64 parent: 4:adf1a74a7f7b
62 parent: 3:1c28f494dae6
65 parent: 3:1c28f494dae6
63 user: test
66 user: test
64 date: Thu Jan 01 00:00:00 1970 +0000
67 date: Thu Jan 01 00:00:00 1970 +0000
65 summary: merge
68 summary: merge
66
69
67 changeset: 4:adf1a74a7f7b
70 changeset: 4:adf1a74a7f7b
68 branch: foo
71 branch: foo
69 parent: 1:6c0e42da283a
72 parent: 1:6c0e42da283a
70 user: test
73 user: test
71 date: Thu Jan 01 00:00:00 1970 +0000
74 date: Thu Jan 01 00:00:00 1970 +0000
72 summary: modify a branch
75 summary: modify a branch
73
76
74 changeset: 3:1c28f494dae6
77 changeset: 3:1c28f494dae6
75 user: test
78 user: test
76 date: Thu Jan 01 00:00:00 1970 +0000
79 date: Thu Jan 01 00:00:00 1970 +0000
77 summary: clear branch name
80 summary: clear branch name
78
81
79 changeset: 2:c21617b13b22
82 changeset: 2:c21617b13b22
80 branch: bar
83 branch: bar
81 user: test
84 user: test
82 date: Thu Jan 01 00:00:00 1970 +0000
85 date: Thu Jan 01 00:00:00 1970 +0000
83 summary: change branch name
86 summary: change branch name
84
87
85 changeset: 1:6c0e42da283a
88 changeset: 1:6c0e42da283a
86 branch: foo
89 branch: foo
87 user: test
90 user: test
88 date: Thu Jan 01 00:00:00 1970 +0000
91 date: Thu Jan 01 00:00:00 1970 +0000
89 summary: add branch name
92 summary: add branch name
90
93
91 changeset: 0:db01e8ea3388
94 changeset: 0:db01e8ea3388
92 user: test
95 user: test
93 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
94 summary: initial
97 summary: initial
95
98
96 $ hg branches
99 $ hg branches
97 foo 5:530046499edf
100 foo 5:530046499edf
98 default 3:1c28f494dae6 (inactive)
101 default 3:1c28f494dae6 (inactive)
99 bar 2:c21617b13b22 (inactive)
102 bar 2:c21617b13b22 (inactive)
100
103
101 $ hg branches -q
104 $ hg branches -q
102 foo
105 foo
103 default
106 default
104 bar
107 bar
105
108
106 Test for invalid branch cache:
109 Test for invalid branch cache:
107
110
108 $ hg rollback
111 $ hg rollback
109 repository tip rolled back to revision 4 (undo commit)
112 repository tip rolled back to revision 4 (undo commit)
110 working directory now based on revisions 4 and 3
113 working directory now based on revisions 4 and 3
111
114
112 $ cp $branchcache .hg/bc-invalid
115 $ cp $branchcache .hg/bc-invalid
113
116
114 $ hg log -r foo
117 $ hg log -r foo
115 changeset: 4:adf1a74a7f7b
118 changeset: 4:adf1a74a7f7b
116 branch: foo
119 branch: foo
117 tag: tip
120 tag: tip
118 parent: 1:6c0e42da283a
121 parent: 1:6c0e42da283a
119 user: test
122 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
123 date: Thu Jan 01 00:00:00 1970 +0000
121 summary: modify a branch
124 summary: modify a branch
122
125
123 $ cp .hg/bc-invalid $branchcache
126 $ cp .hg/bc-invalid $branchcache
124
127
125 $ hg --debug log -r foo
128 $ hg --debug log -r foo
126 invalidating branch cache (tip differs)
129 invalidating branch cache (tip differs)
127 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
130 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
128 branch: foo
131 branch: foo
129 tag: tip
132 tag: tip
130 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
133 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
131 parent: -1:0000000000000000000000000000000000000000
134 parent: -1:0000000000000000000000000000000000000000
132 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
135 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
133 user: test
136 user: test
134 date: Thu Jan 01 00:00:00 1970 +0000
137 date: Thu Jan 01 00:00:00 1970 +0000
135 files: a
138 files: a
136 extra: branch=foo
139 extra: branch=foo
137 description:
140 description:
138 modify a branch
141 modify a branch
139
142
140
143
141 $ rm $branchcache
144 $ rm $branchcache
142 $ echo corrupted > $branchcache
145 $ echo corrupted > $branchcache
143
146
144 $ hg log -qr foo
147 $ hg log -qr foo
145 4:adf1a74a7f7b
148 4:adf1a74a7f7b
146
149
147 $ cat $branchcache
150 $ cat $branchcache
148 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
151 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
149 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
152 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
150 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
153 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
151 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
154 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
152
155
153 Push should update the branch cache:
156 Push should update the branch cache:
154
157
155 $ hg init ../target
158 $ hg init ../target
156
159
157 Pushing just rev 0:
160 Pushing just rev 0:
158
161
159 $ hg push -qr 0 ../target
162 $ hg push -qr 0 ../target
160
163
161 $ cat ../target/$branchcache
164 $ cat ../target/$branchcache
162 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
165 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
163 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
166 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
164
167
165 Pushing everything:
168 Pushing everything:
166
169
167 $ hg push -qf ../target
170 $ hg push -qf ../target
168
171
169 $ cat ../target/$branchcache
172 $ cat ../target/$branchcache
170 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
173 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
171 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
174 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
172 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
175 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
173 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
176 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
174
177
175 Update with no arguments: tipmost revision of the current branch:
178 Update with no arguments: tipmost revision of the current branch:
176
179
177 $ hg up -q -C 0
180 $ hg up -q -C 0
178 $ hg up -q
181 $ hg up -q
179 $ hg id
182 $ hg id
180 1c28f494dae6
183 1c28f494dae6
181
184
182 $ hg up -q 1
185 $ hg up -q 1
183 $ hg up -q
186 $ hg up -q
184 $ hg id
187 $ hg id
185 adf1a74a7f7b (foo) tip
188 adf1a74a7f7b (foo) tip
186
189
187 $ hg branch foobar
190 $ hg branch foobar
188 marked working directory as branch foobar
191 marked working directory as branch foobar
192 (branches are permanent and global, did you want a bookmark?)
189
193
190 $ hg up
194 $ hg up
191 abort: branch foobar not found
195 abort: branch foobar not found
192 [255]
196 [255]
193
197
194 Fastforward merge:
198 Fastforward merge:
195
199
196 $ hg branch ff
200 $ hg branch ff
197 marked working directory as branch ff
201 marked working directory as branch ff
202 (branches are permanent and global, did you want a bookmark?)
198
203
199 $ echo ff > ff
204 $ echo ff > ff
200 $ hg ci -Am'fast forward'
205 $ hg ci -Am'fast forward'
201 adding ff
206 adding ff
202
207
203 $ hg up foo
208 $ hg up foo
204 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
209 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
205
210
206 $ hg merge ff
211 $ hg merge ff
207 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 (branch merge, don't forget to commit)
213 (branch merge, don't forget to commit)
209
214
210 $ hg branch
215 $ hg branch
211 foo
216 foo
212 $ hg commit -m'Merge ff into foo'
217 $ hg commit -m'Merge ff into foo'
213 $ hg parents
218 $ hg parents
214 changeset: 6:185ffbfefa30
219 changeset: 6:185ffbfefa30
215 branch: foo
220 branch: foo
216 tag: tip
221 tag: tip
217 parent: 4:adf1a74a7f7b
222 parent: 4:adf1a74a7f7b
218 parent: 5:1a3c27dc5e11
223 parent: 5:1a3c27dc5e11
219 user: test
224 user: test
220 date: Thu Jan 01 00:00:00 1970 +0000
225 date: Thu Jan 01 00:00:00 1970 +0000
221 summary: Merge ff into foo
226 summary: Merge ff into foo
222
227
223 $ hg manifest
228 $ hg manifest
224 a
229 a
225 ff
230 ff
226
231
227
232
228 Test merging, add 3 default heads and one test head:
233 Test merging, add 3 default heads and one test head:
229
234
230 $ cd ..
235 $ cd ..
231 $ hg init merges
236 $ hg init merges
232 $ cd merges
237 $ cd merges
233 $ echo a > a
238 $ echo a > a
234 $ hg ci -Ama
239 $ hg ci -Ama
235 adding a
240 adding a
236
241
237 $ echo b > b
242 $ echo b > b
238 $ hg ci -Amb
243 $ hg ci -Amb
239 adding b
244 adding b
240
245
241 $ hg up 0
246 $ hg up 0
242 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
247 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
243 $ echo c > c
248 $ echo c > c
244 $ hg ci -Amc
249 $ hg ci -Amc
245 adding c
250 adding c
246 created new head
251 created new head
247
252
248 $ hg up 0
253 $ hg up 0
249 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
254 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
250 $ echo d > d
255 $ echo d > d
251 $ hg ci -Amd
256 $ hg ci -Amd
252 adding d
257 adding d
253 created new head
258 created new head
254
259
255 $ hg up 0
260 $ hg up 0
256 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
261 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
257 $ hg branch test
262 $ hg branch test
258 marked working directory as branch test
263 marked working directory as branch test
264 (branches are permanent and global, did you want a bookmark?)
259 $ echo e >> e
265 $ echo e >> e
260 $ hg ci -Ame
266 $ hg ci -Ame
261 adding e
267 adding e
262
268
263 $ hg log
269 $ hg log
264 changeset: 4:3a1e01ed1df4
270 changeset: 4:3a1e01ed1df4
265 branch: test
271 branch: test
266 tag: tip
272 tag: tip
267 parent: 0:cb9a9f314b8b
273 parent: 0:cb9a9f314b8b
268 user: test
274 user: test
269 date: Thu Jan 01 00:00:00 1970 +0000
275 date: Thu Jan 01 00:00:00 1970 +0000
270 summary: e
276 summary: e
271
277
272 changeset: 3:980f7dc84c29
278 changeset: 3:980f7dc84c29
273 parent: 0:cb9a9f314b8b
279 parent: 0:cb9a9f314b8b
274 user: test
280 user: test
275 date: Thu Jan 01 00:00:00 1970 +0000
281 date: Thu Jan 01 00:00:00 1970 +0000
276 summary: d
282 summary: d
277
283
278 changeset: 2:d36c0562f908
284 changeset: 2:d36c0562f908
279 parent: 0:cb9a9f314b8b
285 parent: 0:cb9a9f314b8b
280 user: test
286 user: test
281 date: Thu Jan 01 00:00:00 1970 +0000
287 date: Thu Jan 01 00:00:00 1970 +0000
282 summary: c
288 summary: c
283
289
284 changeset: 1:d2ae7f538514
290 changeset: 1:d2ae7f538514
285 user: test
291 user: test
286 date: Thu Jan 01 00:00:00 1970 +0000
292 date: Thu Jan 01 00:00:00 1970 +0000
287 summary: b
293 summary: b
288
294
289 changeset: 0:cb9a9f314b8b
295 changeset: 0:cb9a9f314b8b
290 user: test
296 user: test
291 date: Thu Jan 01 00:00:00 1970 +0000
297 date: Thu Jan 01 00:00:00 1970 +0000
292 summary: a
298 summary: a
293
299
294 Implicit merge with test branch as parent:
300 Implicit merge with test branch as parent:
295
301
296 $ hg merge
302 $ hg merge
297 abort: branch 'test' has one head - please merge with an explicit rev
303 abort: branch 'test' has one head - please merge with an explicit rev
298 (run 'hg heads' to see all heads)
304 (run 'hg heads' to see all heads)
299 [255]
305 [255]
300 $ hg up -C default
306 $ hg up -C default
301 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
307 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
302
308
303 Implicit merge with default branch as parent:
309 Implicit merge with default branch as parent:
304
310
305 $ hg merge
311 $ hg merge
306 abort: branch 'default' has 3 heads - please merge with an explicit rev
312 abort: branch 'default' has 3 heads - please merge with an explicit rev
307 (run 'hg heads .' to see heads)
313 (run 'hg heads .' to see heads)
308 [255]
314 [255]
309
315
310 3 branch heads, explicit merge required:
316 3 branch heads, explicit merge required:
311
317
312 $ hg merge 2
318 $ hg merge 2
313 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 (branch merge, don't forget to commit)
320 (branch merge, don't forget to commit)
315 $ hg ci -m merge
321 $ hg ci -m merge
316
322
317 2 branch heads, implicit merge works:
323 2 branch heads, implicit merge works:
318
324
319 $ hg merge
325 $ hg merge
320 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
321 (branch merge, don't forget to commit)
327 (branch merge, don't forget to commit)
322
328
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now