##// END OF EJS Templates
add export, recover, and undo to the man page...
jake@edge2.net -
r196:48827121 default
parent child Browse files
Show More
@@ -1,213 +1,225 b''
1 .\"Generated by db2man.xsl. Don't modify this, modify the source.
1 .\"Generated by db2man.xsl. Don't modify this, modify the source.
2 .de Sh \" Subsection
2 .de Sh \" Subsection
3 .br
3 .br
4 .if t .Sp
4 .if t .Sp
5 .ne 5
5 .ne 5
6 .PP
6 .PP
7 \fB\\$1\fR
7 \fB\\$1\fR
8 .PP
8 .PP
9 ..
9 ..
10 .de Sp \" Vertical space (when we can't use .PP)
10 .de Sp \" Vertical space (when we can't use .PP)
11 .if t .sp .5v
11 .if t .sp .5v
12 .if n .sp
12 .if n .sp
13 ..
13 ..
14 .de Ip \" List item
14 .de Ip \" List item
15 .br
15 .br
16 .ie \\n(.$>=3 .ne \\$3
16 .ie \\n(.$>=3 .ne \\$3
17 .el .ne 3
17 .el .ne 3
18 .IP "\\$1" \\$2
18 .IP "\\$1" \\$2
19 ..
19 ..
20 .TH "HG" 1 "" "" ""
20 .TH "HG" 1 "" "" ""
21 .SH NAME
21 .SH NAME
22 hg \- command line interface to the Mercurial source code management system
22 hg \- command line interface to the Mercurial source code management system
23 .SH "SYNOPSIS"
23 .SH "SYNOPSIS"
24
24
25
25
26 hg [\-v \-d \-q \-y] <command> [command options] [files]
26 hg [\-v \-d \-q \-y] <command> [command options] [files]
27
27
28 .SH "DESCRIPTION"
28 .SH "DESCRIPTION"
29
29
30
30
31 The hg(1) command provides a command line interface to the Mercurial system\&.
31 The hg(1) command provides a command line interface to the Mercurial system\&.
32
32
33 .SH "NOTE"
33 .SH "NOTE"
34
34
35
35
36 Many of the hg commands are not yet subdirectory and/or working directory aware\&. This means that some commands will only work in the top level repository directory or will only accept paths and filenames relative to the top level\&. Merges and commits, in particular, should be done in the top\-level directory\&.
36 Many of the hg commands are not yet subdirectory and/or working directory aware\&. This means that some commands will only work in the top level repository directory or will only accept paths and filenames relative to the top level\&. Merges and commits, in particular, should be done in the top\-level directory\&.
37
37
38 .SH "OPTIONS"
38 .SH "OPTIONS"
39
39
40 .TP
40 .TP
41 --debug, \-d
41 --debug, \-d
42 enable debugging output
42 enable debugging output
43
43
44 .TP
44 .TP
45 --quiet, \-q
45 --quiet, \-q
46 suppress output
46 suppress output
47
47
48 .TP
48 .TP
49 --verbose, \-v
49 --verbose, \-v
50 enable additional output
50 enable additional output
51
51
52 .TP
52 .TP
53 --noninteractive, \-y
53 --noninteractive, \-y
54 do not prompt, assume yes for any required answers
54 do not prompt, assume yes for any required answers
55
55
56 .SH "COMMAND ELEMENTS"
56 .SH "COMMAND ELEMENTS"
57
57
58 .TP
58 .TP
59 files ...
59 files ...
60 indicates one or more filename or relative path filenames
60 indicates one or more filename or relative path filenames
61
61
62 .TP
62 .TP
63 path
63 path
64 indicates a path on the local machine
64 indicates a path on the local machine
65
65
66 .TP
66 .TP
67 revision
67 revision
68 indicates a changeset which can be specified as a changeset id (int), a tag, or a unique substring of the changeset hash value
68 indicates a changeset which can be specified as a changeset id (int), a tag, or a unique substring of the changeset hash value
69
69
70 .TP
70 .TP
71 repository path
71 repository path
72 is either the pathname of a local repository of the URI of a remote repository\&. There are two available URI protocols, http:// which is fast and the old\-http:// protocol which is much slower but does not require python on the web host\&.
72 is either the pathname of a local repository of the URI of a remote repository\&. There are two available URI protocols, http:// which is fast and the old\-http:// protocol which is much slower but does not require python on the web host\&.
73
73
74 .SH "COMMANDS"
74 .SH "COMMANDS"
75
75
76 .TP
76 .TP
77 add [files ...]
77 add [files ...]
78 add the given files to the repository\&. Note that this just schedules the files for addition at the next hg commit time\&.
78 add the given files to the repository\&. Note that this just schedules the files for addition at the next hg commit time\&.
79
79
80 .TP
80 .TP
81 addremove
81 addremove
82 add all new files and remove all missing files from the repository\&. new files are ignored if they match any of the patterns in \&.hgignore
82 add all new files and remove all missing files from the repository\&. new files are ignored if they match any of the patterns in \&.hgignore
83
83
84 .TP
84 .TP
85 annotate [\-r revision \-u \-n \-c] [files ...]
85 annotate [\-r revision \-u \-n \-c] [files ...]
86 list the files with each line showing the revision id responsible for that line\&. \-u will add the author to the revision id, \-c will print the changeset hash, and \-n will ...
86 list the files with each line showing the revision id responsible for that line\&. \-u will add the author to the revision id, \-c will print the changeset hash, and \-n will ...
87
87
88 .TP
88 .TP
89 branch <path>
89 branch <path>
90 create a new branch of the repository indicated by path in the current directory\&. Note that there should not be a repository already initialized in the current directory
90 create a new branch of the repository indicated by path in the current directory\&. Note that there should not be a repository already initialized in the current directory
91
91
92 .TP
92 .TP
93 checkout [revision]
93 checkout [revision]
94 check out the indicated version of the repository into the working directory\&. Note that currently no merge occurs with changed files in the working dir\&.
94 check out the indicated version of the repository into the working directory\&. Note that currently no merge occurs with changed files in the working dir\&.
95
95
96 .TP
96 .TP
97 commit
97 commit
98 commit all changed files in the working dir to the repository\&. This uses the EDITOR environment variable to bring up an editor to add a commit comment\&.
98 commit all changed files in the working dir to the repository\&. This uses the EDITOR environment variable to bring up an editor to add a commit comment\&.
99
99
100 .TP
100 .TP
101 diff [\-r revision] [\-r revision] [files ...]
101 diff [\-r revision] [\-r revision] [files ...]
102 generate a unified diff of the indicated files\&. If there are no revisions specified, the working directory file is compared to the tip, one revision specified indicates a comparison between the working directory file and the specified revision, two revisions compares the two versions specified\&.
102 generate a unified diff of the indicated files\&. If there are no revisions specified, the working directory file is compared to the tip, one revision specified indicates a comparison between the working directory file and the specified revision, two revisions compares the two versions specified\&.
103
103
104 .TP
104 .TP
105 dump <file> [revision]
105 dump <file> [revision]
106 print the indicated revision of the file
106 print the indicated revision of the file
107
107
108 .TP
108 .TP
109 dumpmanifest [revision]
109 dumpmanifest [revision]
110 print the indicated revision of the manifest (list of version controlled files)
110 print the indicated revision of the manifest (list of version controlled files)
111
111
112 .TP
112 .TP
113 export [revision]
114 print the changeset header (author, changeset hash, parent, and commit comment) and the diffs for a particular revision\&.
115
116 .TP
113 history
117 history
114 print the revision history of the repository
118 print the revision history of the repository
115
119
116 .TP
120 .TP
117 init
121 init
118 initialize a repository in the current directory
122 initialize a repository in the current directory
119
123
120 .TP
124 .TP
121 log <file>
125 log <file>
122 print the revision history of the specified file
126 print the revision history of the specified file
123
127
124 .TP
128 .TP
125 merge <repository path>
129 merge <repository path>
126 pull any changes from the specified repository to the repository in the current directory\&. Use the value of the HGMERGE environment variable as a program to resolve any merge conflicts between the two repositories\&. An implicit commit is done at the end of this process if there were any merge conflicts\&. Note that merge does not yet merge with changed files in the working dir\&.
130 pull any changes from the specified repository to the repository in the current directory\&. Use the value of the HGMERGE environment variable as a program to resolve any merge conflicts between the two repositories\&. An implicit commit is done at the end of this process if there were any merge conflicts\&. Note that merge does not yet merge with changed files in the working dir\&.
127
131
128 .TP
132 .TP
133 recover
134 rollback an interrupted transaction
135
136 .TP
129 remove [files ...]
137 remove [files ...]
130 schedule the indicated files for removal from the repository at the next commit
138 schedule the indicated files for removal from the repository at the next commit
131
139
132 .TP
140 .TP
133 serve [\-a addr \-n name \-p port \-t templatedir]
141 serve [\-a addr \-n name \-p port \-t templatedir]
134 this will start an http server, by default on port 8000, that will allow browsing the repository using the hgweb interface and will allow merging from the repository\&. \-a sets the interface address, \-p the port to listen on, \-n the name of the repository and \-t sets the location of the template directory\&.
142 this will start an http server, by default on port 8000, that will allow browsing the repository using the hgweb interface and will allow merging from the repository\&. \-a sets the interface address, \-p the port to listen on, \-n the name of the repository and \-t sets the location of the template directory\&.
135
143
136 .TP
144 .TP
137 status
145 status
138 list new, changed, and missing files in the working directory
146 list new, changed, and missing files in the working directory
139
147
140 .TP
148 .TP
141 tags
149 tags
142 list the current tags
150 list the current tags
143
151
152 .TP
153 undo
154 undo the last transaction
155
144 .SH "ENVIRONMENT VARIABLES"
156 .SH "ENVIRONMENT VARIABLES"
145
157
146 .TP
158 .TP
147 HGMERGE
159 HGMERGE
148 points to an executable to use for resolving merge conflicts, the program will be executed with four arguments: local file, remote file, ancestor file, and original filename\&.
160 points to an executable to use for resolving merge conflicts, the program will be executed with four arguments: local file, remote file, ancestor file, and original filename\&.
149
161
150 .TP
162 .TP
151 HGUSER
163 HGUSER
152 this is the string used for the author value of a commit
164 this is the string used for the author value of a commit
153
165
154 .TP
166 .TP
155 HG_OPTS
167 HG_OPTS
156 this string is used for default arguments to hg
168 this string is used for default arguments to hg
157
169
158 .TP
170 .TP
159 PYTHONPATH
171 PYTHONPATH
160 this is used by Python to find imported modules and needs to be set appropriately based on where mercurial is installed
172 this is used by Python to find imported modules and needs to be set appropriately based on where mercurial is installed
161
173
162 .TP
174 .TP
163 EMAIL
175 EMAIL
164 if HGUSER is not set, this will be used next as the author value for a commit
176 if HGUSER is not set, this will be used next as the author value for a commit
165
177
166 .TP
178 .TP
167 LOGNAME
179 LOGNAME
168 if neither HGUSER nor EMAIL is set, LOGNAME will be used (with @hostname appended) as the author value for a commit
180 if neither HGUSER nor EMAIL is set, LOGNAME will be used (with @hostname appended) as the author value for a commit
169
181
170 .TP
182 .TP
171 EDITOR
183 EDITOR
172 this is the name of the editor to use when committing
184 this is the name of the editor to use when committing
173
185
174 .SH "FILES"
186 .SH "FILES"
175
187
176 .TP
188 .TP
177 \&.hgignore
189 \&.hgignore
178 this file contains regular expressions (one per line) that describe file names that should be ignored by hg
190 this file contains regular expressions (one per line) that describe file names that should be ignored by hg
179
191
180 .TP
192 .TP
181 \&.hgtags
193 \&.hgtags
182 this file contains changeset hash values and text tag names (one of each seperated by spaces) that correspond to tagged versions of the repository contents\&.
194 this file contains changeset hash values and text tag names (one of each seperated by spaces) that correspond to tagged versions of the repository contents\&.
183
195
184 .TP
196 .TP
185 $HOME/\&.hgpaths
197 $HOME/\&.hgpaths
186 this file contains a mapping from a symbolic name to a repository path (which could be a local path or a remote URI), the format is <symbolic name> <repository path> with each mapping on a seperate line
198 this file contains a mapping from a symbolic name to a repository path (which could be a local path or a remote URI), the format is <symbolic name> <repository path> with each mapping on a seperate line
187
199
188 .SH "BUGS"
200 .SH "BUGS"
189
201
190
202
191 Probably lots, please post them to the mailing list (See Resources below) when you find them\&.
203 Probably lots, please post them to the mailing list (See Resources below) when you find them\&.
192
204
193 .SH "AUTHOR"
205 .SH "AUTHOR"
194
206
195
207
196 Written by Matt Mackall <mpm@selenic\&.com>
208 Written by Matt Mackall <mpm@selenic\&.com>
197
209
198 .SH "RESOURCES"
210 .SH "RESOURCES"
199
211
200
212
201 Main Web Site: \fIhttp://selenic.com/mercurial\fR
213 Main Web Site: \fIhttp://selenic.com/mercurial\fR
202
214
203
215
204 Source code repository: \fIhttp://selenic.com/hg\fR
216 Source code repository: \fIhttp://selenic.com/hg\fR
205
217
206
218
207 Mailing list: \fIhttp://selenic.com/mailman/listinfo/mercurial\fR
219 Mailing list: \fIhttp://selenic.com/mailman/listinfo/mercurial\fR
208
220
209 .SH "COPYING"
221 .SH "COPYING"
210
222
211
223
212 Copyright (C) 2005 Matt Mackall\&. Free use of this software is granted under the terms of the GNU General Public License (GPL)\&.
224 Copyright (C) 2005 Matt Mackall\&. Free use of this software is granted under the terms of the GNU General Public License (GPL)\&.
213
225
@@ -1,417 +1,442 b''
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
2 <html>
3 <head>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
5 <meta name="generator" content="AsciiDoc 6.0.3">
5 <meta name="generator" content="AsciiDoc 6.0.3">
6 <meta name="author" content="Matt Mackall">
6 <meta name="author" content="Matt Mackall">
7 <meta name="author-email" content="mpm@selenic.com">
7 <meta name="author-email" content="mpm@selenic.com">
8 <title>HG(1)</title>
8 <title>HG(1)</title>
9 </head>
9 </head>
10 <body>
10 <body>
11 <h1>HG(1)</h1>
11 <h1>HG(1)</h1>
12 <p>
12 <p>
13 <strong>by Matt Mackall</strong><br />
13 <strong>by Matt Mackall</strong><br />
14 <tt>&lt;<a href="mailto:mpm@selenic.com">mpm@selenic.com</a>&gt;</tt><br />
14 <tt>&lt;<a href="mailto:mpm@selenic.com">mpm@selenic.com</a>&gt;</tt><br />
15 v0.5,
15 v0.5,
16 27 May 2005
16 27 May 2005
17 </p>
17 </p>
18 <hr />
18 <hr />
19 <h2>NAME</h2>
19 <h2>NAME</h2>
20 <p>
20 <p>
21 hg - command line interface to the Mercurial source code management system
21 hg - command line interface to the Mercurial source code management system
22 </p>
22 </p>
23 <hr />
23 <hr />
24 <h2>SYNOPSIS</h2>
24 <h2>SYNOPSIS</h2>
25 <p>
25 <p>
26 <em>hg</em> [-v -d -q -y] &lt;command&gt; [command options] [files]
26 <em>hg</em> [-v -d -q -y] &lt;command&gt; [command options] [files]
27 </p>
27 </p>
28 <hr />
28 <hr />
29 <h2>DESCRIPTION</h2>
29 <h2>DESCRIPTION</h2>
30 <p>
30 <p>
31 The hg(1) command provides a command line interface to the Mercurial system.
31 The hg(1) command provides a command line interface to the Mercurial system.
32 </p>
32 </p>
33 <hr />
33 <hr />
34 <h2>NOTE</h2>
34 <h2>NOTE</h2>
35 <p>
35 <p>
36 Many of the hg commands are not yet subdirectory and/or working directory
36 Many of the hg commands are not yet subdirectory and/or working directory
37 aware. This means that some commands will only work in the top level
37 aware. This means that some commands will only work in the top level
38 repository directory or will only accept paths and filenames relative to the
38 repository directory or will only accept paths and filenames relative to the
39 top level. Merges and commits, in particular, should be done in the
39 top level. Merges and commits, in particular, should be done in the
40 top-level directory.
40 top-level directory.
41 </p>
41 </p>
42 <hr />
42 <hr />
43 <h2>OPTIONS</h2>
43 <h2>OPTIONS</h2>
44 <dl>
44 <dl>
45 <dt>
45 <dt>
46 &#8212;debug, -d
46 &#8212;debug, -d
47 </dt>
47 </dt>
48 <dd>
48 <dd>
49
49
50 enable debugging output
50 enable debugging output
51
51
52 </dd>
52 </dd>
53 <dt>
53 <dt>
54 &#8212;quiet, -q
54 &#8212;quiet, -q
55 </dt>
55 </dt>
56 <dd>
56 <dd>
57
57
58 suppress output
58 suppress output
59
59
60 </dd>
60 </dd>
61 <dt>
61 <dt>
62 &#8212;verbose, -v
62 &#8212;verbose, -v
63 </dt>
63 </dt>
64 <dd>
64 <dd>
65
65
66 enable additional output
66 enable additional output
67
67
68 </dd>
68 </dd>
69 <dt>
69 <dt>
70 &#8212;noninteractive, -y
70 &#8212;noninteractive, -y
71 </dt>
71 </dt>
72 <dd>
72 <dd>
73
73
74 do not prompt, assume <em>yes</em> for any required answers
74 do not prompt, assume <em>yes</em> for any required answers
75
75
76 </dd>
76 </dd>
77 </dl>
77 </dl>
78 <hr />
78 <hr />
79 <h2>COMMAND ELEMENTS</h2>
79 <h2>COMMAND ELEMENTS</h2>
80 <dl>
80 <dl>
81 <dt>
81 <dt>
82 files &#8230;
82 files &#8230;
83 </dt>
83 </dt>
84 <dd>
84 <dd>
85
85
86 indicates one or more filename or relative path filenames
86 indicates one or more filename or relative path filenames
87
87
88 </dd>
88 </dd>
89 <dt>
89 <dt>
90 path
90 path
91 </dt>
91 </dt>
92 <dd>
92 <dd>
93
93
94 indicates a path on the local machine
94 indicates a path on the local machine
95
95
96 </dd>
96 </dd>
97 <dt>
97 <dt>
98 revision
98 revision
99 </dt>
99 </dt>
100 <dd>
100 <dd>
101
101
102 indicates a changeset which can be specified as a changeset id (int),
102 indicates a changeset which can be specified as a changeset id (int),
103 a tag, or a unique substring of the changeset hash value
103 a tag, or a unique substring of the changeset hash value
104
104
105 </dd>
105 </dd>
106 <dt>
106 <dt>
107 repository path
107 repository path
108 </dt>
108 </dt>
109 <dd>
109 <dd>
110
110
111 is either the pathname of a local repository of the URI of a remote
111 is either the pathname of a local repository of the URI of a remote
112 repository. There are two available URI protocols, http:// which is
112 repository. There are two available URI protocols, http:// which is
113 fast and the old-http:// protocol which is much slower but does not
113 fast and the old-http:// protocol which is much slower but does not
114 require python on the web host.
114 require python on the web host.
115
115
116 </dd>
116 </dd>
117 </dl>
117 </dl>
118 <hr />
118 <hr />
119 <h2>COMMANDS</h2>
119 <h2>COMMANDS</h2>
120 <dl>
120 <dl>
121 <dt>
121 <dt>
122 add [files &#8230;]
122 add [files &#8230;]
123 </dt>
123 </dt>
124 <dd>
124 <dd>
125
125
126 add the given files to the repository. Note that this just schedules the
126 add the given files to the repository. Note that this just schedules the
127 files for addition at the next hg commit time.
127 files for addition at the next hg commit time.
128
128
129 </dd>
129 </dd>
130 <dt>
130 <dt>
131 addremove
131 addremove
132 </dt>
132 </dt>
133 <dd>
133 <dd>
134
134
135 add all new files and remove all missing files from the repository. new
135 add all new files and remove all missing files from the repository. new
136 files are ignored if they match any of the patterns in .hgignore
136 files are ignored if they match any of the patterns in .hgignore
137
137
138 </dd>
138 </dd>
139 <dt>
139 <dt>
140 annotate [-r revision -u -n -c] [files &#8230;]
140 annotate [-r revision -u -n -c] [files &#8230;]
141 </dt>
141 </dt>
142 <dd>
142 <dd>
143
143
144 list the files with each line showing the revision id responsible
144 list the files with each line showing the revision id responsible
145 for that line. -u will add the author to the revision id, -c will
145 for that line. -u will add the author to the revision id, -c will
146 print the changeset hash, and -n will &#8230;
146 print the changeset hash, and -n will &#8230;
147
147
148 </dd>
148 </dd>
149 <dt>
149 <dt>
150 branch &lt;path&gt;
150 branch &lt;path&gt;
151 </dt>
151 </dt>
152 <dd>
152 <dd>
153
153
154 create a new branch of the repository indicated by path in the current
154 create a new branch of the repository indicated by path in the current
155 directory. Note that there should not be a repository already initialized
155 directory. Note that there should not be a repository already initialized
156 in the current directory
156 in the current directory
157
157
158 </dd>
158 </dd>
159 <dt>
159 <dt>
160 checkout [revision]
160 checkout [revision]
161 </dt>
161 </dt>
162 <dd>
162 <dd>
163
163
164 check out the indicated version of the repository into the working
164 check out the indicated version of the repository into the working
165 directory. Note that currently no merge occurs with changed files
165 directory. Note that currently no merge occurs with changed files
166 in the working dir.
166 in the working dir.
167
167
168 </dd>
168 </dd>
169 <dt>
169 <dt>
170 commit
170 commit
171 </dt>
171 </dt>
172 <dd>
172 <dd>
173
173
174 commit all changed files in the working dir to the repository. This uses
174 commit all changed files in the working dir to the repository. This uses
175 the EDITOR environment variable to bring up an editor to add a commit
175 the EDITOR environment variable to bring up an editor to add a commit
176 comment.
176 comment.
177
177
178 </dd>
178 </dd>
179 <dt>
179 <dt>
180 diff [-r revision] [-r revision] [files &#8230;]
180 diff [-r revision] [-r revision] [files &#8230;]
181 </dt>
181 </dt>
182 <dd>
182 <dd>
183
183
184 generate a unified diff of the indicated files. If there are no
184 generate a unified diff of the indicated files. If there are no
185 revisions specified, the working directory file is compared to
185 revisions specified, the working directory file is compared to
186 the tip, one revision specified indicates a comparison between the
186 the tip, one revision specified indicates a comparison between the
187 working directory file and the specified revision, two revisions
187 working directory file and the specified revision, two revisions
188 compares the two versions specified.
188 compares the two versions specified.
189
189
190 </dd>
190 </dd>
191 <dt>
191 <dt>
192 dump &lt;file&gt; [revision]
192 dump &lt;file&gt; [revision]
193 </dt>
193 </dt>
194 <dd>
194 <dd>
195
195
196 print the indicated revision of the file
196 print the indicated revision of the file
197
197
198 </dd>
198 </dd>
199 <dt>
199 <dt>
200 dumpmanifest [revision]
200 dumpmanifest [revision]
201 </dt>
201 </dt>
202 <dd>
202 <dd>
203
203
204 print the indicated revision of the manifest (list of version controlled
204 print the indicated revision of the manifest (list of version controlled
205 files)
205 files)
206
206
207 </dd>
207 </dd>
208 <dt>
208 <dt>
209 export [revision]
210 </dt>
211 <dd>
212
213 print the changeset header (author, changeset hash, parent, and commit
214 comment) and the diffs for a particular revision.
215
216 </dd>
217 <dt>
209 history
218 history
210 </dt>
219 </dt>
211 <dd>
220 <dd>
212
221
213 print the revision history of the repository
222 print the revision history of the repository
214
223
215 </dd>
224 </dd>
216 <dt>
225 <dt>
217 init
226 init
218 </dt>
227 </dt>
219 <dd>
228 <dd>
220
229
221 initialize a repository in the current directory
230 initialize a repository in the current directory
222
231
223 </dd>
232 </dd>
224 <dt>
233 <dt>
225 log &lt;file&gt;
234 log &lt;file&gt;
226 </dt>
235 </dt>
227 <dd>
236 <dd>
228
237
229 print the revision history of the specified file
238 print the revision history of the specified file
230
239
231 </dd>
240 </dd>
232 <dt>
241 <dt>
233 merge &lt;repository path&gt;
242 merge &lt;repository path&gt;
234 </dt>
243 </dt>
235 <dd>
244 <dd>
236
245
237 pull any changes from the specified repository to the repository in the
246 pull any changes from the specified repository to the repository in the
238 current directory. Use the value of the HGMERGE environment variable
247 current directory. Use the value of the HGMERGE environment variable
239 as a program to resolve any merge conflicts between the two repositories.
248 as a program to resolve any merge conflicts between the two repositories.
240 An implicit commit is done at the end of this process if there were any
249 An implicit commit is done at the end of this process if there were any
241 merge conflicts. Note that merge does not yet merge with changed files
250 merge conflicts. Note that merge does not yet merge with changed files
242 in the working dir.
251 in the working dir.
243
252
244 </dd>
253 </dd>
245 <dt>
254 <dt>
255 recover
256 </dt>
257 <dd>
258
259 rollback an interrupted transaction
260
261 </dd>
262 <dt>
246 remove [files &#8230;]
263 remove [files &#8230;]
247 </dt>
264 </dt>
248 <dd>
265 <dd>
249
266
250 schedule the indicated files for removal from the repository at the next
267 schedule the indicated files for removal from the repository at the next
251 commit
268 commit
252
269
253 </dd>
270 </dd>
254 <dt>
271 <dt>
255 serve [-a addr -n name -p port -t templatedir]
272 serve [-a addr -n name -p port -t templatedir]
256 </dt>
273 </dt>
257 <dd>
274 <dd>
258
275
259 this will start an http server, by default on port 8000, that will
276 this will start an http server, by default on port 8000, that will
260 allow browsing the repository using the hgweb interface and will allow
277 allow browsing the repository using the hgweb interface and will allow
261 merging from the repository. -a sets the interface address, -p the
278 merging from the repository. -a sets the interface address, -p the
262 port to listen on, -n the name of the repository and -t sets the
279 port to listen on, -n the name of the repository and -t sets the
263 location of the template directory.
280 location of the template directory.
264
281
265 </dd>
282 </dd>
266 <dt>
283 <dt>
267 status
284 status
268 </dt>
285 </dt>
269 <dd>
286 <dd>
270
287
271 list new, changed, and missing files in the working directory
288 list new, changed, and missing files in the working directory
272
289
273 </dd>
290 </dd>
274 <dt>
291 <dt>
275 tags
292 tags
276 </dt>
293 </dt>
277 <dd>
294 <dd>
278
295
279 list the current tags
296 list the current tags
280
297
281 </dd>
298 </dd>
299 <dt>
300 undo
301 </dt>
302 <dd>
303
304 undo the last transaction
305
306 </dd>
282 </dl>
307 </dl>
283 <hr />
308 <hr />
284 <h2>ENVIRONMENT VARIABLES</h2>
309 <h2>ENVIRONMENT VARIABLES</h2>
285 <dl>
310 <dl>
286 <dt>
311 <dt>
287 HGMERGE
312 HGMERGE
288 </dt>
313 </dt>
289 <dd>
314 <dd>
290
315
291 points to an executable to use for resolving merge conflicts, the
316 points to an executable to use for resolving merge conflicts, the
292 program will be executed with four arguments: local file, remote
317 program will be executed with four arguments: local file, remote
293 file, ancestor file, and original filename.
318 file, ancestor file, and original filename.
294
319
295 </dd>
320 </dd>
296 <dt>
321 <dt>
297 HGUSER
322 HGUSER
298 </dt>
323 </dt>
299 <dd>
324 <dd>
300
325
301 this is the string used for the author value of a commit
326 this is the string used for the author value of a commit
302
327
303 </dd>
328 </dd>
304 <dt>
329 <dt>
305 HG_OPTS
330 HG_OPTS
306 </dt>
331 </dt>
307 <dd>
332 <dd>
308
333
309 this string is used for default arguments to hg
334 this string is used for default arguments to hg
310
335
311 </dd>
336 </dd>
312 <dt>
337 <dt>
313 PYTHONPATH
338 PYTHONPATH
314 </dt>
339 </dt>
315 <dd>
340 <dd>
316
341
317 this is used by Python to find imported modules and needs to be set
342 this is used by Python to find imported modules and needs to be set
318 appropriately based on where mercurial is installed
343 appropriately based on where mercurial is installed
319
344
320 </dd>
345 </dd>
321 <dt>
346 <dt>
322 EMAIL
347 EMAIL
323 </dt>
348 </dt>
324 <dd>
349 <dd>
325
350
326 if HGUSER is not set, this will be used next as the author value for
351 if HGUSER is not set, this will be used next as the author value for
327 a commit
352 a commit
328
353
329 </dd>
354 </dd>
330 <dt>
355 <dt>
331 LOGNAME
356 LOGNAME
332 </dt>
357 </dt>
333 <dd>
358 <dd>
334
359
335 if neither HGUSER nor EMAIL is set, LOGNAME will be used (with
360 if neither HGUSER nor EMAIL is set, LOGNAME will be used (with
336 <em>@hostname</em> appended) as the author value for a commit
361 <em>@hostname</em> appended) as the author value for a commit
337
362
338 </dd>
363 </dd>
339 <dt>
364 <dt>
340 EDITOR
365 EDITOR
341 </dt>
366 </dt>
342 <dd>
367 <dd>
343
368
344 this is the name of the editor to use when committing
369 this is the name of the editor to use when committing
345
370
346 </dd>
371 </dd>
347 </dl>
372 </dl>
348 <hr />
373 <hr />
349 <h2>FILES</h2>
374 <h2>FILES</h2>
350 <dl>
375 <dl>
351 <dt>
376 <dt>
352 .hgignore
377 .hgignore
353 </dt>
378 </dt>
354 <dd>
379 <dd>
355
380
356 this file contains regular expressions (one per line) that describe file
381 this file contains regular expressions (one per line) that describe file
357 names that should be ignored by hg
382 names that should be ignored by hg
358
383
359 </dd>
384 </dd>
360 <dt>
385 <dt>
361 .hgtags
386 .hgtags
362 </dt>
387 </dt>
363 <dd>
388 <dd>
364
389
365 this file contains changeset hash values and text tag names (one of each
390 this file contains changeset hash values and text tag names (one of each
366 seperated by spaces) that correspond to tagged versions of the repository
391 seperated by spaces) that correspond to tagged versions of the repository
367 contents.
392 contents.
368
393
369 </dd>
394 </dd>
370 <dt>
395 <dt>
371 $HOME/.hgpaths
396 $HOME/.hgpaths
372 </dt>
397 </dt>
373 <dd>
398 <dd>
374
399
375 this file contains a mapping from a symbolic name to a repository path
400 this file contains a mapping from a symbolic name to a repository path
376 (which could be a local path or a remote URI), the format is
401 (which could be a local path or a remote URI), the format is
377 &lt;symbolic name&gt; &lt;repository path&gt; with each mapping on a seperate line
402 &lt;symbolic name&gt; &lt;repository path&gt; with each mapping on a seperate line
378
403
379 </dd>
404 </dd>
380 </dl>
405 </dl>
381 <hr />
406 <hr />
382 <h2>BUGS</h2>
407 <h2>BUGS</h2>
383 <p>
408 <p>
384 Probably lots, please post them to the mailing list (See Resources below)
409 Probably lots, please post them to the mailing list (See Resources below)
385 when you find them.
410 when you find them.
386 </p>
411 </p>
387 <hr />
412 <hr />
388 <h2>AUTHOR</h2>
413 <h2>AUTHOR</h2>
389 <p>
414 <p>
390 Written by Matt Mackall &lt;mpm@selenic.com&gt;
415 Written by Matt Mackall &lt;mpm@selenic.com&gt;
391 </p>
416 </p>
392 <hr />
417 <hr />
393 <h2>RESOURCES</h2>
418 <h2>RESOURCES</h2>
394 <p>
419 <p>
395 <a href="http://selenic.com/mercurial">Main Web Site</a>
420 <a href="http://selenic.com/mercurial">Main Web Site</a>
396 </p>
421 </p>
397 <p>
422 <p>
398 <a href="http://selenic.com/hg">Source code repository</a>
423 <a href="http://selenic.com/hg">Source code repository</a>
399 </p>
424 </p>
400 <p>
425 <p>
401 <a href="http://selenic.com/mailman/listinfo/mercurial">Mailing list</a>
426 <a href="http://selenic.com/mailman/listinfo/mercurial">Mailing list</a>
402 </p>
427 </p>
403 <hr />
428 <hr />
404 <h2>COPYING</h2>
429 <h2>COPYING</h2>
405 <p>
430 <p>
406 Copyright &#169; 2005 Matt Mackall.
431 Copyright &#169; 2005 Matt Mackall.
407 Free use of this software is granted under the terms of the GNU General
432 Free use of this software is granted under the terms of the GNU General
408 Public License (GPL).
433 Public License (GPL).
409 </p>
434 </p>
410 <p></p>
435 <p></p>
411 <p></p>
436 <p></p>
412 <hr /><p><small>
437 <hr /><p><small>
413 Version 0.5<br />
438 Version 0.5<br />
414 Last updated 27-May-2005 15:07:30 MDT
439 Last updated 27-May-2005 15:51:06 MDT
415 </small></p>
440 </small></p>
416 </body>
441 </body>
417 </html>
442 </html>
@@ -1,202 +1,212 b''
1 HG(1)
1 HG(1)
2 =====
2 =====
3 Matt Mackall <mpm@selenic.com>
3 Matt Mackall <mpm@selenic.com>
4 v0.5, 27 May 2005
4 v0.5, 27 May 2005
5
5
6 NAME
6 NAME
7 ----
7 ----
8 hg - command line interface to the Mercurial source code management system
8 hg - command line interface to the Mercurial source code management system
9
9
10 SYNOPSIS
10 SYNOPSIS
11 --------
11 --------
12 'hg' [-v -d -q -y] <command> [command options] [files]
12 'hg' [-v -d -q -y] <command> [command options] [files]
13
13
14 DESCRIPTION
14 DESCRIPTION
15 -----------
15 -----------
16 The hg(1) command provides a command line interface to the Mercurial system.
16 The hg(1) command provides a command line interface to the Mercurial system.
17
17
18 NOTE
18 NOTE
19 ----
19 ----
20 Many of the hg commands are not yet subdirectory and/or working directory
20 Many of the hg commands are not yet subdirectory and/or working directory
21 aware. This means that some commands will only work in the top level
21 aware. This means that some commands will only work in the top level
22 repository directory or will only accept paths and filenames relative to the
22 repository directory or will only accept paths and filenames relative to the
23 top level. Merges and commits, in particular, should be done in the
23 top level. Merges and commits, in particular, should be done in the
24 top-level directory.
24 top-level directory.
25
25
26 OPTIONS
26 OPTIONS
27 -------
27 -------
28 --debug, -d::
28 --debug, -d::
29 enable debugging output
29 enable debugging output
30
30
31 --quiet, -q::
31 --quiet, -q::
32 suppress output
32 suppress output
33
33
34 --verbose, -v::
34 --verbose, -v::
35 enable additional output
35 enable additional output
36
36
37 --noninteractive, -y::
37 --noninteractive, -y::
38 do not prompt, assume 'yes' for any required answers
38 do not prompt, assume 'yes' for any required answers
39
39
40 COMMAND ELEMENTS
40 COMMAND ELEMENTS
41 ----------------
41 ----------------
42
42
43 files ...::
43 files ...::
44 indicates one or more filename or relative path filenames
44 indicates one or more filename or relative path filenames
45
45
46 path::
46 path::
47 indicates a path on the local machine
47 indicates a path on the local machine
48
48
49 revision::
49 revision::
50 indicates a changeset which can be specified as a changeset id (int),
50 indicates a changeset which can be specified as a changeset id (int),
51 a tag, or a unique substring of the changeset hash value
51 a tag, or a unique substring of the changeset hash value
52
52
53 repository path::
53 repository path::
54 is either the pathname of a local repository of the URI of a remote
54 is either the pathname of a local repository of the URI of a remote
55 repository. There are two available URI protocols, http:// which is
55 repository. There are two available URI protocols, http:// which is
56 fast and the old-http:// protocol which is much slower but does not
56 fast and the old-http:// protocol which is much slower but does not
57 require python on the web host.
57 require python on the web host.
58
58
59 COMMANDS
59 COMMANDS
60 --------
60 --------
61 add [files ...]::
61 add [files ...]::
62 add the given files to the repository. Note that this just schedules the
62 add the given files to the repository. Note that this just schedules the
63 files for addition at the next hg commit time.
63 files for addition at the next hg commit time.
64
64
65 addremove::
65 addremove::
66 add all new files and remove all missing files from the repository. new
66 add all new files and remove all missing files from the repository. new
67 files are ignored if they match any of the patterns in .hgignore
67 files are ignored if they match any of the patterns in .hgignore
68
68
69 annotate [-r revision -u -n -c] [files ...]::
69 annotate [-r revision -u -n -c] [files ...]::
70 list the files with each line showing the revision id responsible
70 list the files with each line showing the revision id responsible
71 for that line. -u will add the author to the revision id, -c will
71 for that line. -u will add the author to the revision id, -c will
72 print the changeset hash, and -n will ...
72 print the changeset hash, and -n will ...
73
73
74 branch <path>::
74 branch <path>::
75 create a new branch of the repository indicated by path in the current
75 create a new branch of the repository indicated by path in the current
76 directory. Note that there should not be a repository already initialized
76 directory. Note that there should not be a repository already initialized
77 in the current directory
77 in the current directory
78
78
79 checkout [revision]::
79 checkout [revision]::
80 check out the indicated version of the repository into the working
80 check out the indicated version of the repository into the working
81 directory. Note that currently no merge occurs with changed files
81 directory. Note that currently no merge occurs with changed files
82 in the working dir.
82 in the working dir.
83
83
84 commit::
84 commit::
85 commit all changed files in the working dir to the repository. This uses
85 commit all changed files in the working dir to the repository. This uses
86 the EDITOR environment variable to bring up an editor to add a commit
86 the EDITOR environment variable to bring up an editor to add a commit
87 comment.
87 comment.
88
88
89 diff [-r revision] [-r revision] [files ...]::
89 diff [-r revision] [-r revision] [files ...]::
90 generate a unified diff of the indicated files. If there are no
90 generate a unified diff of the indicated files. If there are no
91 revisions specified, the working directory file is compared to
91 revisions specified, the working directory file is compared to
92 the tip, one revision specified indicates a comparison between the
92 the tip, one revision specified indicates a comparison between the
93 working directory file and the specified revision, two revisions
93 working directory file and the specified revision, two revisions
94 compares the two versions specified.
94 compares the two versions specified.
95
95
96 dump <file> [revision]::
96 dump <file> [revision]::
97 print the indicated revision of the file
97 print the indicated revision of the file
98
98
99 dumpmanifest [revision]::
99 dumpmanifest [revision]::
100 print the indicated revision of the manifest (list of version controlled
100 print the indicated revision of the manifest (list of version controlled
101 files)
101 files)
102
102
103 export [revision]::
104 print the changeset header (author, changeset hash, parent, and commit
105 comment) and the diffs for a particular revision.
106
103 history::
107 history::
104 print the revision history of the repository
108 print the revision history of the repository
105
109
106 init::
110 init::
107 initialize a repository in the current directory
111 initialize a repository in the current directory
108
112
109 log <file>::
113 log <file>::
110 print the revision history of the specified file
114 print the revision history of the specified file
111
115
112 merge <repository path>::
116 merge <repository path>::
113 pull any changes from the specified repository to the repository in the
117 pull any changes from the specified repository to the repository in the
114 current directory. Use the value of the HGMERGE environment variable
118 current directory. Use the value of the HGMERGE environment variable
115 as a program to resolve any merge conflicts between the two repositories.
119 as a program to resolve any merge conflicts between the two repositories.
116 An implicit commit is done at the end of this process if there were any
120 An implicit commit is done at the end of this process if there were any
117 merge conflicts. Note that merge does not yet merge with changed files
121 merge conflicts. Note that merge does not yet merge with changed files
118 in the working dir.
122 in the working dir.
119
123
124 recover::
125 rollback an interrupted transaction
126
120 remove [files ...]::
127 remove [files ...]::
121 schedule the indicated files for removal from the repository at the next
128 schedule the indicated files for removal from the repository at the next
122 commit
129 commit
123
130
124 serve [-a addr -n name -p port -t templatedir]::
131 serve [-a addr -n name -p port -t templatedir]::
125 this will start an http server, by default on port 8000, that will
132 this will start an http server, by default on port 8000, that will
126 allow browsing the repository using the hgweb interface and will allow
133 allow browsing the repository using the hgweb interface and will allow
127 merging from the repository. -a sets the interface address, -p the
134 merging from the repository. -a sets the interface address, -p the
128 port to listen on, -n the name of the repository and -t sets the
135 port to listen on, -n the name of the repository and -t sets the
129 location of the template directory.
136 location of the template directory.
130
137
131 status::
138 status::
132 list new, changed, and missing files in the working directory
139 list new, changed, and missing files in the working directory
133
140
134 tags::
141 tags::
135 list the current tags
142 list the current tags
136
143
144 undo::
145 undo the last transaction
146
137 ENVIRONMENT VARIABLES
147 ENVIRONMENT VARIABLES
138 ---------------------
148 ---------------------
139 HGMERGE::
149 HGMERGE::
140 points to an executable to use for resolving merge conflicts, the
150 points to an executable to use for resolving merge conflicts, the
141 program will be executed with four arguments: local file, remote
151 program will be executed with four arguments: local file, remote
142 file, ancestor file, and original filename.
152 file, ancestor file, and original filename.
143
153
144 HGUSER::
154 HGUSER::
145 this is the string used for the author value of a commit
155 this is the string used for the author value of a commit
146
156
147 HG_OPTS::
157 HG_OPTS::
148 this string is used for default arguments to hg
158 this string is used for default arguments to hg
149
159
150 PYTHONPATH::
160 PYTHONPATH::
151 this is used by Python to find imported modules and needs to be set
161 this is used by Python to find imported modules and needs to be set
152 appropriately based on where mercurial is installed
162 appropriately based on where mercurial is installed
153
163
154 EMAIL::
164 EMAIL::
155 if HGUSER is not set, this will be used next as the author value for
165 if HGUSER is not set, this will be used next as the author value for
156 a commit
166 a commit
157
167
158 LOGNAME::
168 LOGNAME::
159 if neither HGUSER nor EMAIL is set, LOGNAME will be used (with
169 if neither HGUSER nor EMAIL is set, LOGNAME will be used (with
160 '@hostname' appended) as the author value for a commit
170 '@hostname' appended) as the author value for a commit
161
171
162 EDITOR::
172 EDITOR::
163 this is the name of the editor to use when committing
173 this is the name of the editor to use when committing
164
174
165 FILES
175 FILES
166 -----
176 -----
167 .hgignore::
177 .hgignore::
168 this file contains regular expressions (one per line) that describe file
178 this file contains regular expressions (one per line) that describe file
169 names that should be ignored by hg
179 names that should be ignored by hg
170
180
171 .hgtags::
181 .hgtags::
172 this file contains changeset hash values and text tag names (one of each
182 this file contains changeset hash values and text tag names (one of each
173 seperated by spaces) that correspond to tagged versions of the repository
183 seperated by spaces) that correspond to tagged versions of the repository
174 contents.
184 contents.
175
185
176 $HOME/.hgpaths::
186 $HOME/.hgpaths::
177 this file contains a mapping from a symbolic name to a repository path
187 this file contains a mapping from a symbolic name to a repository path
178 (which could be a local path or a remote URI), the format is
188 (which could be a local path or a remote URI), the format is
179 <symbolic name> <repository path> with each mapping on a seperate line
189 <symbolic name> <repository path> with each mapping on a seperate line
180
190
181 BUGS
191 BUGS
182 ----
192 ----
183 Probably lots, please post them to the mailing list (See Resources below)
193 Probably lots, please post them to the mailing list (See Resources below)
184 when you find them.
194 when you find them.
185
195
186 AUTHOR
196 AUTHOR
187 ------
197 ------
188 Written by Matt Mackall <mpm@selenic.com>
198 Written by Matt Mackall <mpm@selenic.com>
189
199
190 RESOURCES
200 RESOURCES
191 ---------
201 ---------
192 http://selenic.com/mercurial[Main Web Site]
202 http://selenic.com/mercurial[Main Web Site]
193
203
194 http://selenic.com/hg[Source code repository]
204 http://selenic.com/hg[Source code repository]
195
205
196 http://selenic.com/mailman/listinfo/mercurial[Mailing list]
206 http://selenic.com/mailman/listinfo/mercurial[Mailing list]
197
207
198 COPYING
208 COPYING
199 -------
209 -------
200 Copyright (C) 2005 Matt Mackall.
210 Copyright (C) 2005 Matt Mackall.
201 Free use of this software is granted under the terms of the GNU General
211 Free use of this software is granted under the terms of the GNU General
202 Public License (GPL).
212 Public License (GPL).
@@ -1,588 +1,589 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # mercurial - a minimal scalable distributed SCM
3 # mercurial - a minimal scalable distributed SCM
4 # v0.5b "katje"
4 # v0.5b "katje"
5 #
5 #
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
7 #
7 #
8 # This software may be used and distributed according to the terms
8 # This software may be used and distributed according to the terms
9 # of the GNU General Public License, incorporated herein by reference.
9 # of the GNU General Public License, incorporated herein by reference.
10
10
11 # the psyco compiler makes commits a bit faster
11 # the psyco compiler makes commits a bit faster
12 # and makes changegroup merge about 20 times slower!
12 # and makes changegroup merge about 20 times slower!
13 # try:
13 # try:
14 # import psyco
14 # import psyco
15 # psyco.full()
15 # psyco.full()
16 # except:
16 # except:
17 # pass
17 # pass
18
18
19 import sys, os, time
19 import sys, os, time
20 from mercurial import hg, mdiff, fancyopts
20 from mercurial import hg, mdiff, fancyopts
21
21
22 def help():
22 def help():
23 ui.status("""\
23 ui.status("""\
24 commands:
24 commands:
25
25
26 add [files...] add the given files in the next commit
26 add [files...] add the given files in the next commit
27 addremove add all new files, delete all missing files
27 addremove add all new files, delete all missing files
28 annotate [files...] show changeset number per file line
28 annotate [files...] show changeset number per file line
29 branch <path> create a branch of <path> in this directory
29 branch <path> create a branch of <path> in this directory
30 checkout [changeset] checkout the latest or given changeset
30 checkout [changeset] checkout the latest or given changeset
31 commit commit all changes to the repository
31 commit commit all changes to the repository
32 diff [files...] diff working directory (or selected files)
32 diff [files...] diff working directory (or selected files)
33 dump <file> [rev] dump the latest or given revision of a file
33 dump <file> [rev] dump the latest or given revision of a file
34 dumpmanifest [rev] dump the latest or given revision of the manifest
34 dumpmanifest [rev] dump the latest or given revision of the manifest
35 export <rev> dump the changeset header and diffs for a revision
35 history show changeset history
36 history show changeset history
36 init create a new repository in this directory
37 init create a new repository in this directory
37 log <file> show revision history of a single file
38 log <file> show revision history of a single file
38 merge <path> merge changes from <path> into local repository
39 merge <path> merge changes from <path> into local repository
39 recover rollback an interrupted transaction
40 recover rollback an interrupted transaction
40 remove [files...] remove the given files in the next commit
41 remove [files...] remove the given files in the next commit
41 serve export the repository via HTTP
42 serve export the repository via HTTP
42 status show new, missing, and changed files in working dir
43 status show new, missing, and changed files in working dir
43 tags show current changeset tags
44 tags show current changeset tags
44 undo undo the last transaction
45 undo undo the last transaction
45 """)
46 """)
46
47
47 def filterfiles(list, files):
48 def filterfiles(list, files):
48 l = [ x for x in list if x in files ]
49 l = [ x for x in list if x in files ]
49
50
50 for f in files:
51 for f in files:
51 if f[-1] != os.sep: f += os.sep
52 if f[-1] != os.sep: f += os.sep
52 l += [ x for x in list if x.startswith(f) ]
53 l += [ x for x in list if x.startswith(f) ]
53 return l
54 return l
54
55
55 def diff(files = None, node1 = None, node2 = None):
56 def diff(files = None, node1 = None, node2 = None):
56 def date(c):
57 def date(c):
57 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
58 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
58
59
59 if node2:
60 if node2:
60 change = repo.changelog.read(node2)
61 change = repo.changelog.read(node2)
61 mmap2 = repo.manifest.read(change[0])
62 mmap2 = repo.manifest.read(change[0])
62 (c, a, d) = repo.diffrevs(node1, node2)
63 (c, a, d) = repo.diffrevs(node1, node2)
63 def read(f): return repo.file(f).read(mmap2[f])
64 def read(f): return repo.file(f).read(mmap2[f])
64 date2 = date(change)
65 date2 = date(change)
65 else:
66 else:
66 date2 = time.asctime()
67 date2 = time.asctime()
67 if not node1:
68 if not node1:
68 node1 = repo.current
69 node1 = repo.current
69 (c, a, d) = repo.diffdir(repo.root, node1)
70 (c, a, d) = repo.diffdir(repo.root, node1)
70 a = [] # ignore unknown files in repo, by popular request
71 a = [] # ignore unknown files in repo, by popular request
71 def read(f): return file(os.path.join(repo.root, f)).read()
72 def read(f): return file(os.path.join(repo.root, f)).read()
72
73
73 change = repo.changelog.read(node1)
74 change = repo.changelog.read(node1)
74 mmap = repo.manifest.read(change[0])
75 mmap = repo.manifest.read(change[0])
75 date1 = date(change)
76 date1 = date(change)
76
77
77 if files:
78 if files:
78 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
79 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
79
80
80 for f in c:
81 for f in c:
81 to = ""
82 to = ""
82 if mmap.has_key(f):
83 if mmap.has_key(f):
83 to = repo.file(f).read(mmap[f])
84 to = repo.file(f).read(mmap[f])
84 tn = read(f)
85 tn = read(f)
85 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
86 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
86 for f in a:
87 for f in a:
87 to = ""
88 to = ""
88 tn = read(f)
89 tn = read(f)
89 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
90 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
90 for f in d:
91 for f in d:
91 to = repo.file(f).read(mmap[f])
92 to = repo.file(f).read(mmap[f])
92 tn = ""
93 tn = ""
93 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
94 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
94
95
95 options = {}
96 options = {}
96 opts = [('v', 'verbose', None, 'verbose'),
97 opts = [('v', 'verbose', None, 'verbose'),
97 ('d', 'debug', None, 'debug'),
98 ('d', 'debug', None, 'debug'),
98 ('q', 'quiet', None, 'quiet'),
99 ('q', 'quiet', None, 'quiet'),
99 ('y', 'noninteractive', None, 'run non-interactively'),
100 ('y', 'noninteractive', None, 'run non-interactively'),
100 ]
101 ]
101
102
102 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
103 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
103 'hg [options] <command> [command options] [files]')
104 'hg [options] <command> [command options] [files]')
104
105
105 try:
106 try:
106 cmd = args[0]
107 cmd = args[0]
107 args = args[1:]
108 args = args[1:]
108 except:
109 except:
109 cmd = ""
110 cmd = ""
110
111
111 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
112 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
112 not options["noninteractive"])
113 not options["noninteractive"])
113
114
114 if cmd == "init":
115 if cmd == "init":
115 repo = hg.repository(ui, ".", create=1)
116 repo = hg.repository(ui, ".", create=1)
116 sys.exit(0)
117 sys.exit(0)
117 elif cmd == "branch" or cmd == "clone":
118 elif cmd == "branch" or cmd == "clone":
118 os.system("cp -al %s/.hg .hg" % args[0])
119 os.system("cp -al %s/.hg .hg" % args[0])
119 sys.exit(0)
120 sys.exit(0)
120 elif cmd == "help":
121 elif cmd == "help":
121 help()
122 help()
122 sys.exit(0)
123 sys.exit(0)
123 else:
124 else:
124 try:
125 try:
125 repo = hg.repository(ui=ui)
126 repo = hg.repository(ui=ui)
126 except IOError:
127 except IOError:
127 ui.warn("Unable to open repository\n")
128 ui.warn("Unable to open repository\n")
128 sys.exit(0)
129 sys.exit(0)
129
130
130 relpath = None
131 relpath = None
131 if os.getcwd() != repo.root:
132 if os.getcwd() != repo.root:
132 relpath = os.getcwd()[len(repo.root) + 1: ]
133 relpath = os.getcwd()[len(repo.root) + 1: ]
133
134
134 if cmd == "checkout" or cmd == "co":
135 if cmd == "checkout" or cmd == "co":
135 node = repo.changelog.tip()
136 node = repo.changelog.tip()
136 if args:
137 if args:
137 node = repo.lookup(args[0])
138 node = repo.lookup(args[0])
138 repo.checkout(node)
139 repo.checkout(node)
139
140
140 elif cmd == "add":
141 elif cmd == "add":
141 repo.add(args)
142 repo.add(args)
142
143
143 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
144 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
144 repo.remove(args)
145 repo.remove(args)
145
146
146 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
147 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
147 if 1:
148 if 1:
148 if len(args) > 0:
149 if len(args) > 0:
149 repo.commit(repo.current, args)
150 repo.commit(repo.current, args)
150 else:
151 else:
151 repo.commit(repo.current)
152 repo.commit(repo.current)
152
153
153 elif cmd == "import" or cmd == "patch":
154 elif cmd == "import" or cmd == "patch":
154 try:
155 try:
155 import psyco
156 import psyco
156 psyco.full()
157 psyco.full()
157 except:
158 except:
158 pass
159 pass
159
160
160 ioptions = {}
161 ioptions = {}
161 opts = [('p', 'strip', 1, 'path strip'),
162 opts = [('p', 'strip', 1, 'path strip'),
162 ('b', 'base', "", 'base path'),
163 ('b', 'base', "", 'base path'),
163 ('q', 'quiet', "", 'silence diff')
164 ('q', 'quiet', "", 'silence diff')
164 ]
165 ]
165
166
166 args = fancyopts.fancyopts(args, opts, ioptions,
167 args = fancyopts.fancyopts(args, opts, ioptions,
167 'hg import [options] <patch names>')
168 'hg import [options] <patch names>')
168 d = ioptions["base"]
169 d = ioptions["base"]
169 strip = ioptions["strip"]
170 strip = ioptions["strip"]
170 quiet = ioptions["quiet"] and "> /dev/null" or ""
171 quiet = ioptions["quiet"] and "> /dev/null" or ""
171
172
172 for patch in args:
173 for patch in args:
173 ui.status("applying %s\n" % patch)
174 ui.status("applying %s\n" % patch)
174 pf = os.path.join(d, patch)
175 pf = os.path.join(d, patch)
175
176
176 text = ""
177 text = ""
177 for l in file(pf):
178 for l in file(pf):
178 if l[:4] == "--- ": break
179 if l[:4] == "--- ": break
179 text += l
180 text += l
180
181
181 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
182 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
182 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
183 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
183 f.close()
184 f.close()
184
185
185 if files:
186 if files:
186 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
187 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
187 raise "patch failed!"
188 raise "patch failed!"
188 repo.commit(repo.current, files, text)
189 repo.commit(repo.current, files, text)
189
190
190 elif cmd == "status":
191 elif cmd == "status":
191 (c, a, d) = repo.diffdir(repo.root, repo.current)
192 (c, a, d) = repo.diffdir(repo.root, repo.current)
192 if relpath:
193 if relpath:
193 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
194 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
194
195
195 for f in c: print "C", f
196 for f in c: print "C", f
196 for f in a: print "?", f
197 for f in a: print "?", f
197 for f in d: print "R", f
198 for f in d: print "R", f
198
199
199 elif cmd == "diff":
200 elif cmd == "diff":
200 revs = []
201 revs = []
201
202
202 if args:
203 if args:
203 doptions = {}
204 doptions = {}
204 opts = [('r', 'revision', [], 'revision')]
205 opts = [('r', 'revision', [], 'revision')]
205 args = fancyopts.fancyopts(args, opts, doptions,
206 args = fancyopts.fancyopts(args, opts, doptions,
206 'hg diff [options] [files]')
207 'hg diff [options] [files]')
207 revs = map(lambda x: repo.lookup(x), doptions['revision'])
208 revs = map(lambda x: repo.lookup(x), doptions['revision'])
208
209
209 if len(revs) > 2:
210 if len(revs) > 2:
210 self.ui.warn("too many revisions to diff\n")
211 self.ui.warn("too many revisions to diff\n")
211 sys.exit(1)
212 sys.exit(1)
212
213
213 if relpath:
214 if relpath:
214 if not args: args = [ relpath ]
215 if not args: args = [ relpath ]
215 else: args = [ os.path.join(relpath, x) for x in args ]
216 else: args = [ os.path.join(relpath, x) for x in args ]
216
217
217 diff(args, *revs)
218 diff(args, *revs)
218
219
219 elif cmd == "annotate":
220 elif cmd == "annotate":
220 bcache = {}
221 bcache = {}
221
222
222 def getnode(rev):
223 def getnode(rev):
223 return hg.short(repo.changelog.node(rev))
224 return hg.short(repo.changelog.node(rev))
224
225
225 def getname(rev):
226 def getname(rev):
226 try:
227 try:
227 return bcache[rev]
228 return bcache[rev]
228 except KeyError:
229 except KeyError:
229 cl = repo.changelog.read(repo.changelog.node(rev))
230 cl = repo.changelog.read(repo.changelog.node(rev))
230 name = cl[1]
231 name = cl[1]
231 f = name.find('@')
232 f = name.find('@')
232 if f >= 0:
233 if f >= 0:
233 name = name[:f]
234 name = name[:f]
234 bcache[rev] = name
235 bcache[rev] = name
235 return name
236 return name
236
237
237 aoptions = {}
238 aoptions = {}
238 opts = [('r', 'revision', '', 'revision'),
239 opts = [('r', 'revision', '', 'revision'),
239 ('u', 'user', None, 'show user'),
240 ('u', 'user', None, 'show user'),
240 ('n', 'number', None, 'show revision number'),
241 ('n', 'number', None, 'show revision number'),
241 ('c', 'changeset', None, 'show changeset')]
242 ('c', 'changeset', None, 'show changeset')]
242
243
243 args = fancyopts.fancyopts(args, opts, aoptions,
244 args = fancyopts.fancyopts(args, opts, aoptions,
244 'hg annotate [-u] [-c] [-n] [-r id] [files]')
245 'hg annotate [-u] [-c] [-n] [-r id] [files]')
245
246
246 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
247 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
247 if not aoptions['user'] and not aoptions['changeset']:
248 if not aoptions['user'] and not aoptions['changeset']:
248 aoptions['number'] = 1
249 aoptions['number'] = 1
249
250
250 if args:
251 if args:
251 if relpath: args = [ os.path.join(relpath, x) for x in args ]
252 if relpath: args = [ os.path.join(relpath, x) for x in args ]
252 node = repo.current
253 node = repo.current
253 if aoptions['revision']:
254 if aoptions['revision']:
254 node = repo.changelog.lookup(aoptions['revision'])
255 node = repo.changelog.lookup(aoptions['revision'])
255 change = repo.changelog.read(node)
256 change = repo.changelog.read(node)
256 mmap = repo.manifest.read(change[0])
257 mmap = repo.manifest.read(change[0])
257 maxuserlen = 0
258 maxuserlen = 0
258 maxchangelen = 0
259 maxchangelen = 0
259 for f in args:
260 for f in args:
260 lines = repo.file(f).annotate(mmap[f])
261 lines = repo.file(f).annotate(mmap[f])
261 pieces = []
262 pieces = []
262
263
263 for o, f in opmap:
264 for o, f in opmap:
264 if aoptions[o]:
265 if aoptions[o]:
265 l = [ f(n) for n,t in lines ]
266 l = [ f(n) for n,t in lines ]
266 m = max(map(len, l))
267 m = max(map(len, l))
267 pieces.append([ "%*s" % (m, x) for x in l])
268 pieces.append([ "%*s" % (m, x) for x in l])
268
269
269 for p,l in zip(zip(*pieces), lines):
270 for p,l in zip(zip(*pieces), lines):
270 sys.stdout.write(" ".join(p) + ": " + l[1])
271 sys.stdout.write(" ".join(p) + ": " + l[1])
271
272
272 elif cmd == "export":
273 elif cmd == "export":
273 node = repo.lookup(args[0])
274 node = repo.lookup(args[0])
274 prev, other = repo.changelog.parents(node)
275 prev, other = repo.changelog.parents(node)
275 change = repo.changelog.read(node)
276 change = repo.changelog.read(node)
276 print "# HG changeset patch"
277 print "# HG changeset patch"
277 print "# User %s" % change[1]
278 print "# User %s" % change[1]
278 print "# Node ID %s" % hg.hex(node)
279 print "# Node ID %s" % hg.hex(node)
279 print "# Parent %s" % hg.hex(prev)
280 print "# Parent %s" % hg.hex(prev)
280 print
281 print
281 if other != hg.nullid:
282 if other != hg.nullid:
282 print "# Parent %s" % hg.hex(other)
283 print "# Parent %s" % hg.hex(other)
283 print change[4]
284 print change[4]
284
285
285 diff(None, prev, node)
286 diff(None, prev, node)
286
287
287 elif cmd == "debugchangegroup":
288 elif cmd == "debugchangegroup":
288 newer = repo.newer(map(repo.lookup, args))
289 newer = repo.newer(map(repo.lookup, args))
289 for chunk in repo.changegroup(newer):
290 for chunk in repo.changegroup(newer):
290 sys.stdout.write(chunk)
291 sys.stdout.write(chunk)
291
292
292 elif cmd == "debugaddchangegroup":
293 elif cmd == "debugaddchangegroup":
293 data = sys.stdin.read()
294 data = sys.stdin.read()
294 repo.addchangegroup(data)
295 repo.addchangegroup(data)
295
296
296 elif cmd == "addremove":
297 elif cmd == "addremove":
297 (c, a, d) = repo.diffdir(repo.root, repo.current)
298 (c, a, d) = repo.diffdir(repo.root, repo.current)
298 repo.add(a)
299 repo.add(a)
299 repo.remove(d)
300 repo.remove(d)
300
301
301 elif cmd == "history":
302 elif cmd == "history":
302 for i in range(repo.changelog.count()):
303 for i in range(repo.changelog.count()):
303 n = repo.changelog.node(i)
304 n = repo.changelog.node(i)
304 changes = repo.changelog.read(n)
305 changes = repo.changelog.read(n)
305 (p1, p2) = repo.changelog.parents(n)
306 (p1, p2) = repo.changelog.parents(n)
306 (h, h1, h2) = map(hg.hex, (n, p1, p2))
307 (h, h1, h2) = map(hg.hex, (n, p1, p2))
307 (i1, i2) = map(repo.changelog.rev, (p1, p2))
308 (i1, i2) = map(repo.changelog.rev, (p1, p2))
308 print "rev: %4d:%s" % (i, h)
309 print "rev: %4d:%s" % (i, h)
309 print "parents: %4d:%s" % (i1, h1)
310 print "parents: %4d:%s" % (i1, h1)
310 if i2: print " %4d:%s" % (i2, h2)
311 if i2: print " %4d:%s" % (i2, h2)
311 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
312 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
312 hg.hex(changes[0]))
313 hg.hex(changes[0]))
313 print "user:", changes[1]
314 print "user:", changes[1]
314 print "date:", time.asctime(
315 print "date:", time.asctime(
315 time.localtime(float(changes[2].split(' ')[0])))
316 time.localtime(float(changes[2].split(' ')[0])))
316 if ui.verbose: print "files:", " ".join(changes[3])
317 if ui.verbose: print "files:", " ".join(changes[3])
317 print "description:"
318 print "description:"
318 print changes[4]
319 print changes[4]
319
320
320 elif cmd == "tip":
321 elif cmd == "tip":
321 n = repo.changelog.tip()
322 n = repo.changelog.tip()
322 t = repo.changelog.rev(n)
323 t = repo.changelog.rev(n)
323 ui.status("%d:%s\n" % (t, hg.hex(n)))
324 ui.status("%d:%s\n" % (t, hg.hex(n)))
324
325
325 elif cmd == "log":
326 elif cmd == "log":
326
327
327 if len(args) == 1:
328 if len(args) == 1:
328 if relpath:
329 if relpath:
329 args[0] = os.path.join(relpath, args[0])
330 args[0] = os.path.join(relpath, args[0])
330
331
331 r = repo.file(args[0])
332 r = repo.file(args[0])
332 for i in range(r.count()):
333 for i in range(r.count()):
333 n = r.node(i)
334 n = r.node(i)
334 (p1, p2) = r.parents(n)
335 (p1, p2) = r.parents(n)
335 (h, h1, h2) = map(hg.hex, (n, p1, p2))
336 (h, h1, h2) = map(hg.hex, (n, p1, p2))
336 (i1, i2) = map(r.rev, (p1, p2))
337 (i1, i2) = map(r.rev, (p1, p2))
337 cr = r.linkrev(n)
338 cr = r.linkrev(n)
338 cn = hg.hex(repo.changelog.node(cr))
339 cn = hg.hex(repo.changelog.node(cr))
339 print "rev: %4d:%s" % (i, h)
340 print "rev: %4d:%s" % (i, h)
340 print "changeset: %4d:%s" % (cr, cn)
341 print "changeset: %4d:%s" % (cr, cn)
341 print "parents: %4d:%s" % (i1, h1)
342 print "parents: %4d:%s" % (i1, h1)
342 if i2: print " %4d:%s" % (i2, h2)
343 if i2: print " %4d:%s" % (i2, h2)
343 changes = repo.changelog.read(repo.changelog.node(cr))
344 changes = repo.changelog.read(repo.changelog.node(cr))
344 print "user: %s" % changes[1]
345 print "user: %s" % changes[1]
345 print "date: %s" % time.asctime(
346 print "date: %s" % time.asctime(
346 time.localtime(float(changes[2].split(' ')[0])))
347 time.localtime(float(changes[2].split(' ')[0])))
347 print "description:"
348 print "description:"
348 print changes[4]
349 print changes[4]
349 print
350 print
350 elif len(args) > 1:
351 elif len(args) > 1:
351 print "too many args"
352 print "too many args"
352 else:
353 else:
353 print "missing filename"
354 print "missing filename"
354
355
355 elif cmd == "dump":
356 elif cmd == "dump":
356 if args:
357 if args:
357 r = repo.file(args[0])
358 r = repo.file(args[0])
358 n = r.tip()
359 n = r.tip()
359 if len(args) > 1: n = r.lookup(args[1])
360 if len(args) > 1: n = r.lookup(args[1])
360 sys.stdout.write(r.read(n))
361 sys.stdout.write(r.read(n))
361 else:
362 else:
362 print "missing filename"
363 print "missing filename"
363
364
364 elif cmd == "dumpmanifest":
365 elif cmd == "dumpmanifest":
365 n = repo.manifest.tip()
366 n = repo.manifest.tip()
366 if len(args) > 0:
367 if len(args) > 0:
367 n = repo.manifest.lookup(args[0])
368 n = repo.manifest.lookup(args[0])
368 m = repo.manifest.read(n)
369 m = repo.manifest.read(n)
369 files = m.keys()
370 files = m.keys()
370 files.sort()
371 files.sort()
371
372
372 for f in files:
373 for f in files:
373 print hg.hex(m[f]), f
374 print hg.hex(m[f]), f
374
375
375 elif cmd == "debugindex":
376 elif cmd == "debugindex":
376 if ".hg" not in args[0]:
377 if ".hg" not in args[0]:
377 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
378 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
378
379
379 r = hg.revlog(open, args[0], "")
380 r = hg.revlog(open, args[0], "")
380 print " rev offset length base linkrev"+\
381 print " rev offset length base linkrev"+\
381 " p1 p2 nodeid"
382 " p1 p2 nodeid"
382 for i in range(r.count()):
383 for i in range(r.count()):
383 e = r.index[i]
384 e = r.index[i]
384 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
385 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
385 i, e[0], e[1], e[2], e[3],
386 i, e[0], e[1], e[2], e[3],
386 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
387 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
387
388
388 elif cmd == "debugindexdot":
389 elif cmd == "debugindexdot":
389 if ".hg" not in args[0]:
390 if ".hg" not in args[0]:
390 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
391 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
391
392
392 r = hg.revlog(open, args[0], "")
393 r = hg.revlog(open, args[0], "")
393 print "digraph G {"
394 print "digraph G {"
394 for i in range(r.count()):
395 for i in range(r.count()):
395 e = r.index[i]
396 e = r.index[i]
396 print "\t%d -> %d" % (r.rev(e[4]), i)
397 print "\t%d -> %d" % (r.rev(e[4]), i)
397 if e[5] != hg.nullid:
398 if e[5] != hg.nullid:
398 print "\t%d -> %d" % (r.rev(e[5]), i)
399 print "\t%d -> %d" % (r.rev(e[5]), i)
399 print "}"
400 print "}"
400
401
401 elif cmd == "merge":
402 elif cmd == "merge":
402 (c, a, d) = repo.diffdir(repo.root, repo.current)
403 (c, a, d) = repo.diffdir(repo.root, repo.current)
403 if c:
404 if c:
404 ui.warn("aborting (outstanding changes in working directory)\n")
405 ui.warn("aborting (outstanding changes in working directory)\n")
405 sys.exit(1)
406 sys.exit(1)
406
407
407 if args:
408 if args:
408 paths = {}
409 paths = {}
409 try:
410 try:
410 pf = os.path.join(os.environ["HOME"], ".hgpaths")
411 pf = os.path.join(os.environ["HOME"], ".hgpaths")
411 for l in file(pf):
412 for l in file(pf):
412 name, path = l.split()
413 name, path = l.split()
413 paths[name] = path
414 paths[name] = path
414 except:
415 except:
415 pass
416 pass
416
417
417 if args[0] in paths: args[0] = paths[args[0]]
418 if args[0] in paths: args[0] = paths[args[0]]
418
419
419 other = hg.repository(ui, args[0])
420 other = hg.repository(ui, args[0])
420 cg = repo.getchangegroup(other)
421 cg = repo.getchangegroup(other)
421 repo.addchangegroup(cg)
422 repo.addchangegroup(cg)
422 else:
423 else:
423 print "missing source repository"
424 print "missing source repository"
424
425
425 elif cmd == "tags":
426 elif cmd == "tags":
426 repo.lookup(0) # prime the cache
427 repo.lookup(0) # prime the cache
427 i = repo.tags.items()
428 i = repo.tags.items()
428 i.sort()
429 i.sort()
429 for k, n in i:
430 for k, n in i:
430 try:
431 try:
431 r = repo.changelog.rev(n)
432 r = repo.changelog.rev(n)
432 except KeyError:
433 except KeyError:
433 r = "?"
434 r = "?"
434 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
435 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
435
436
436 elif cmd == "recover":
437 elif cmd == "recover":
437 repo.recover()
438 repo.recover()
438
439
439 elif cmd == "undo":
440 elif cmd == "undo":
440 repo.recover("undo")
441 repo.recover("undo")
441
442
442 elif cmd == "verify":
443 elif cmd == "verify":
443 filelinkrevs = {}
444 filelinkrevs = {}
444 filenodes = {}
445 filenodes = {}
445 manifestchangeset = {}
446 manifestchangeset = {}
446 changesets = revisions = files = 0
447 changesets = revisions = files = 0
447 errors = 0
448 errors = 0
448
449
449 ui.status("checking changesets\n")
450 ui.status("checking changesets\n")
450 for i in range(repo.changelog.count()):
451 for i in range(repo.changelog.count()):
451 changesets += 1
452 changesets += 1
452 n = repo.changelog.node(i)
453 n = repo.changelog.node(i)
453 for p in repo.changelog.parents(n):
454 for p in repo.changelog.parents(n):
454 if p not in repo.changelog.nodemap:
455 if p not in repo.changelog.nodemap:
455 ui.warn("changeset %s has unknown parent %s\n" %
456 ui.warn("changeset %s has unknown parent %s\n" %
456 (hg.short(n), hg.short(p)))
457 (hg.short(n), hg.short(p)))
457 errors += 1
458 errors += 1
458 try:
459 try:
459 changes = repo.changelog.read(n)
460 changes = repo.changelog.read(n)
460 except Exception, inst:
461 except Exception, inst:
461 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
462 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
462 errors += 1
463 errors += 1
463
464
464 manifestchangeset[changes[0]] = n
465 manifestchangeset[changes[0]] = n
465 for f in changes[3]:
466 for f in changes[3]:
466 revisions += 1
467 revisions += 1
467 filelinkrevs.setdefault(f, []).append(i)
468 filelinkrevs.setdefault(f, []).append(i)
468
469
469 ui.status("checking manifests\n")
470 ui.status("checking manifests\n")
470 for i in range(repo.manifest.count()):
471 for i in range(repo.manifest.count()):
471 n = repo.manifest.node(i)
472 n = repo.manifest.node(i)
472 for p in repo.manifest.parents(n):
473 for p in repo.manifest.parents(n):
473 if p not in repo.manifest.nodemap:
474 if p not in repo.manifest.nodemap:
474 ui.warn("manifest %s has unknown parent %s\n" %
475 ui.warn("manifest %s has unknown parent %s\n" %
475 (hg.short(n), hg.short(p)))
476 (hg.short(n), hg.short(p)))
476 errors += 1
477 errors += 1
477 ca = repo.changelog.node(repo.manifest.linkrev(n))
478 ca = repo.changelog.node(repo.manifest.linkrev(n))
478 cc = manifestchangeset[n]
479 cc = manifestchangeset[n]
479 if ca != cc:
480 if ca != cc:
480 ui.warn("manifest %s points to %s, not %s\n" %
481 ui.warn("manifest %s points to %s, not %s\n" %
481 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
482 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
482 errors += 1
483 errors += 1
483
484
484 try:
485 try:
485 delta = mdiff.patchtext(repo.manifest.delta(n))
486 delta = mdiff.patchtext(repo.manifest.delta(n))
486 except KeyboardInterrupt:
487 except KeyboardInterrupt:
487 print "aborted"
488 print "aborted"
488 sys.exit(0)
489 sys.exit(0)
489 except Exception, inst:
490 except Exception, inst:
490 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
491 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
491 errors += 1
492 errors += 1
492
493
493 ff = [ l.split('\0') for l in delta.splitlines() ]
494 ff = [ l.split('\0') for l in delta.splitlines() ]
494 for f, fn in ff:
495 for f, fn in ff:
495 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
496 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
496
497
497 ui.status("crosschecking files in changesets and manifests\n")
498 ui.status("crosschecking files in changesets and manifests\n")
498 for f in filenodes:
499 for f in filenodes:
499 if f not in filelinkrevs:
500 if f not in filelinkrevs:
500 ui.warn("file %s in manifest but not in changesets\n" % f)
501 ui.warn("file %s in manifest but not in changesets\n" % f)
501 errors += 1
502 errors += 1
502
503
503 for f in filelinkrevs:
504 for f in filelinkrevs:
504 if f not in filenodes:
505 if f not in filenodes:
505 ui.warn("file %s in changeset but not in manifest\n" % f)
506 ui.warn("file %s in changeset but not in manifest\n" % f)
506 errors += 1
507 errors += 1
507
508
508 ui.status("checking files\n")
509 ui.status("checking files\n")
509 ff = filenodes.keys()
510 ff = filenodes.keys()
510 ff.sort()
511 ff.sort()
511 for f in ff:
512 for f in ff:
512 if f == "/dev/null": continue
513 if f == "/dev/null": continue
513 files += 1
514 files += 1
514 fl = repo.file(f)
515 fl = repo.file(f)
515 nodes = { hg.nullid: 1 }
516 nodes = { hg.nullid: 1 }
516 for i in range(fl.count()):
517 for i in range(fl.count()):
517 n = fl.node(i)
518 n = fl.node(i)
518
519
519 if n not in filenodes[f]:
520 if n not in filenodes[f]:
520 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
521 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
521 print len(filenodes[f].keys()), fl.count(), f
522 print len(filenodes[f].keys()), fl.count(), f
522 errors += 1
523 errors += 1
523 else:
524 else:
524 del filenodes[f][n]
525 del filenodes[f][n]
525
526
526 flr = fl.linkrev(n)
527 flr = fl.linkrev(n)
527 if flr not in filelinkrevs[f]:
528 if flr not in filelinkrevs[f]:
528 ui.warn("%s:%s points to unexpected changeset rev %d\n"
529 ui.warn("%s:%s points to unexpected changeset rev %d\n"
529 % (f, hg.short(n), fl.linkrev(n)))
530 % (f, hg.short(n), fl.linkrev(n)))
530 errors += 1
531 errors += 1
531 else:
532 else:
532 filelinkrevs[f].remove(flr)
533 filelinkrevs[f].remove(flr)
533
534
534 # verify contents
535 # verify contents
535 try:
536 try:
536 t = fl.read(n)
537 t = fl.read(n)
537 except Exception, inst:
538 except Exception, inst:
538 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
539 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
539 errors += 1
540 errors += 1
540
541
541 # verify parents
542 # verify parents
542 (p1, p2) = fl.parents(n)
543 (p1, p2) = fl.parents(n)
543 if p1 not in nodes:
544 if p1 not in nodes:
544 ui.warn("file %s:%s unknown parent 1 %s" %
545 ui.warn("file %s:%s unknown parent 1 %s" %
545 (f, hg.short(n), hg.short(p1)))
546 (f, hg.short(n), hg.short(p1)))
546 errors += 1
547 errors += 1
547 if p2 not in nodes:
548 if p2 not in nodes:
548 ui.warn("file %s:%s unknown parent 2 %s" %
549 ui.warn("file %s:%s unknown parent 2 %s" %
549 (f, hg.short(n), hg.short(p1)))
550 (f, hg.short(n), hg.short(p1)))
550 errors += 1
551 errors += 1
551 nodes[n] = 1
552 nodes[n] = 1
552
553
553 # cross-check
554 # cross-check
554 for flr in filelinkrevs[f]:
555 for flr in filelinkrevs[f]:
555 ui.warn("changeset rev %d not in %s\n" % (flr, f))
556 ui.warn("changeset rev %d not in %s\n" % (flr, f))
556 errors += 1
557 errors += 1
557
558
558 for node in filenodes[f]:
559 for node in filenodes[f]:
559 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
560 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
560 errors += 1
561 errors += 1
561
562
562 ui.status("%d files, %d changesets, %d total revisions\n" %
563 ui.status("%d files, %d changesets, %d total revisions\n" %
563 (files, changesets, revisions))
564 (files, changesets, revisions))
564
565
565 if errors:
566 if errors:
566 ui.warn("%d integrity errors encountered!\n" % errors)
567 ui.warn("%d integrity errors encountered!\n" % errors)
567 sys.exit(1)
568 sys.exit(1)
568
569
569 elif cmd == "serve":
570 elif cmd == "serve":
570 from mercurial import hgweb
571 from mercurial import hgweb
571
572
572 soptions = {}
573 soptions = {}
573 opts = [('p', 'port', 8000, 'listen port'),
574 opts = [('p', 'port', 8000, 'listen port'),
574 ('a', 'address', '', 'interface address'),
575 ('a', 'address', '', 'interface address'),
575 ('n', 'name', os.getcwd(), 'repository name'),
576 ('n', 'name', os.getcwd(), 'repository name'),
576 ('t', 'templates', "", 'template map')
577 ('t', 'templates', "", 'template map')
577 ]
578 ]
578
579
579 args = fancyopts.fancyopts(args, opts, soptions,
580 args = fancyopts.fancyopts(args, opts, soptions,
580 'hg serve [options]')
581 'hg serve [options]')
581
582
582 hgweb.server(repo.root, soptions["name"], soptions["templates"],
583 hgweb.server(repo.root, soptions["name"], soptions["templates"],
583 soptions["address"], soptions["port"])
584 soptions["address"], soptions["port"])
584
585
585 else:
586 else:
586 if cmd: ui.warn("unknown command\n\n")
587 if cmd: ui.warn("unknown command\n\n")
587 help()
588 help()
588 sys.exit(1)
589 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now