##// END OF EJS Templates
Add ui.slash hgrc setting...
Alexis S. L. Carvalho -
r4527:b422b558 default
parent child Browse files
Show More
@@ -1,551 +1,556
1 1 HGRC(5)
2 2 =======
3 3 Bryan O'Sullivan <bos@serpentine.com>
4 4
5 5 NAME
6 6 ----
7 7 hgrc - configuration files for Mercurial
8 8
9 9 SYNOPSIS
10 10 --------
11 11
12 12 The Mercurial system uses a set of configuration files to control
13 13 aspects of its behaviour.
14 14
15 15 FILES
16 16 -----
17 17
18 18 Mercurial reads configuration data from several files, if they exist.
19 19 The names of these files depend on the system on which Mercurial is
20 20 installed.
21 21
22 22 (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc::
23 23 (Unix) <install-root>/etc/mercurial/hgrc::
24 24 Per-installation configuration files, searched for in the
25 25 directory where Mercurial is installed. For example, if installed
26 26 in /shared/tools, Mercurial will look in
27 27 /shared/tools/etc/mercurial/hgrc. Options in these files apply to
28 28 all Mercurial commands executed by any user in any directory.
29 29
30 30 (Unix) /etc/mercurial/hgrc.d/*.rc::
31 31 (Unix) /etc/mercurial/hgrc::
32 32 (Windows) C:\Mercurial\Mercurial.ini::
33 33 Per-system configuration files, for the system on which Mercurial
34 34 is running. Options in these files apply to all Mercurial
35 35 commands executed by any user in any directory. Options in these
36 36 files override per-installation options.
37 37
38 38 (Unix) $HOME/.hgrc::
39 39 (Windows) C:\Documents and Settings\USERNAME\Mercurial.ini::
40 40 (Windows) $HOME\Mercurial.ini::
41 41 Per-user configuration file, for the user running Mercurial.
42 42 Options in this file apply to all Mercurial commands executed by
43 43 any user in any directory. Options in this file override
44 44 per-installation and per-system options.
45 45 On Windows system, one of these is chosen exclusively according
46 46 to definition of HOME environment variable.
47 47
48 48 (Unix, Windows) <repo>/.hg/hgrc::
49 49 Per-repository configuration options that only apply in a
50 50 particular repository. This file is not version-controlled, and
51 51 will not get transferred during a "clone" operation. Options in
52 52 this file override options in all other configuration files.
53 53 On Unix, most of this file will be ignored if it doesn't belong
54 54 to a trusted user or to a trusted group. See the documentation
55 55 for the trusted section below for more details.
56 56
57 57 SYNTAX
58 58 ------
59 59
60 60 A configuration file consists of sections, led by a "[section]" header
61 61 and followed by "name: value" entries; "name=value" is also accepted.
62 62
63 63 [spam]
64 64 eggs=ham
65 65 green=
66 66 eggs
67 67
68 68 Each line contains one entry. If the lines that follow are indented,
69 69 they are treated as continuations of that entry.
70 70
71 71 Leading whitespace is removed from values. Empty lines are skipped.
72 72
73 73 The optional values can contain format strings which refer to other
74 74 values in the same section, or values in a special DEFAULT section.
75 75
76 76 Lines beginning with "#" or ";" are ignored and may be used to provide
77 77 comments.
78 78
79 79 SECTIONS
80 80 --------
81 81
82 82 This section describes the different sections that may appear in a
83 83 Mercurial "hgrc" file, the purpose of each section, its possible
84 84 keys, and their possible values.
85 85
86 86 decode/encode::
87 87 Filters for transforming files on checkout/checkin. This would
88 88 typically be used for newline processing or other
89 89 localization/canonicalization of files.
90 90
91 91 Filters consist of a filter pattern followed by a filter command.
92 92 Filter patterns are globs by default, rooted at the repository
93 93 root. For example, to match any file ending in ".txt" in the root
94 94 directory only, use the pattern "*.txt". To match any file ending
95 95 in ".c" anywhere in the repository, use the pattern "**.c".
96 96
97 97 The filter command can start with a specifier, either "pipe:" or
98 98 "tempfile:". If no specifier is given, "pipe:" is used by default.
99 99
100 100 A "pipe:" command must accept data on stdin and return the
101 101 transformed data on stdout.
102 102
103 103 Pipe example:
104 104
105 105 [encode]
106 106 # uncompress gzip files on checkin to improve delta compression
107 107 # note: not necessarily a good idea, just an example
108 108 *.gz = pipe: gunzip
109 109
110 110 [decode]
111 111 # recompress gzip files when writing them to the working dir (we
112 112 # can safely omit "pipe:", because it's the default)
113 113 *.gz = gzip
114 114
115 115 A "tempfile:" command is a template. The string INFILE is replaced
116 116 with the name of a temporary file that contains the data to be
117 117 filtered by the command. The string OUTFILE is replaced with the
118 118 name of an empty temporary file, where the filtered data must be
119 119 written by the command.
120 120
121 121 NOTE: the tempfile mechanism is recommended for Windows systems,
122 122 where the standard shell I/O redirection operators often have
123 123 strange effects. In particular, if you are doing line ending
124 124 conversion on Windows using the popular dos2unix and unix2dos
125 125 programs, you *must* use the tempfile mechanism, as using pipes will
126 126 corrupt the contents of your files.
127 127
128 128 Tempfile example:
129 129
130 130 [encode]
131 131 # convert files to unix line ending conventions on checkin
132 132 **.txt = tempfile: dos2unix -n INFILE OUTFILE
133 133
134 134 [decode]
135 135 # convert files to windows line ending conventions when writing
136 136 # them to the working dir
137 137 **.txt = tempfile: unix2dos -n INFILE OUTFILE
138 138
139 139 defaults::
140 140 Use the [defaults] section to define command defaults, i.e. the
141 141 default options/arguments to pass to the specified commands.
142 142
143 143 The following example makes 'hg log' run in verbose mode, and
144 144 'hg status' show only the modified files, by default.
145 145
146 146 [defaults]
147 147 log = -v
148 148 status = -m
149 149
150 150 The actual commands, instead of their aliases, must be used when
151 151 defining command defaults. The command defaults will also be
152 152 applied to the aliases of the commands defined.
153 153
154 154 diff::
155 155 Settings used when displaying diffs. They are all boolean and
156 156 defaults to False.
157 157 git;;
158 158 Use git extended diff format.
159 159 nodates;;
160 160 Don't include dates in diff headers.
161 161 showfunc;;
162 162 Show which function each change is in.
163 163 ignorews;;
164 164 Ignore white space when comparing lines.
165 165 ignorewsamount;;
166 166 Ignore changes in the amount of white space.
167 167 ignoreblanklines;;
168 168 Ignore changes whose lines are all blank.
169 169
170 170 email::
171 171 Settings for extensions that send email messages.
172 172 from;;
173 173 Optional. Email address to use in "From" header and SMTP envelope
174 174 of outgoing messages.
175 175 to;;
176 176 Optional. Comma-separated list of recipients' email addresses.
177 177 cc;;
178 178 Optional. Comma-separated list of carbon copy recipients'
179 179 email addresses.
180 180 bcc;;
181 181 Optional. Comma-separated list of blind carbon copy
182 182 recipients' email addresses. Cannot be set interactively.
183 183 method;;
184 184 Optional. Method to use to send email messages. If value is
185 185 "smtp" (default), use SMTP (see section "[smtp]" for
186 186 configuration). Otherwise, use as name of program to run that
187 187 acts like sendmail (takes "-f" option for sender, list of
188 188 recipients on command line, message on stdin). Normally, setting
189 189 this to "sendmail" or "/usr/sbin/sendmail" is enough to use
190 190 sendmail to send messages.
191 191
192 192 Email example:
193 193
194 194 [email]
195 195 from = Joseph User <joe.user@example.com>
196 196 method = /usr/sbin/sendmail
197 197
198 198 extensions::
199 199 Mercurial has an extension mechanism for adding new features. To
200 200 enable an extension, create an entry for it in this section.
201 201
202 202 If you know that the extension is already in Python's search path,
203 203 you can give the name of the module, followed by "=", with nothing
204 204 after the "=".
205 205
206 206 Otherwise, give a name that you choose, followed by "=", followed by
207 207 the path to the ".py" file (including the file name extension) that
208 208 defines the extension.
209 209
210 210 Example for ~/.hgrc:
211 211
212 212 [extensions]
213 213 # (the mq extension will get loaded from mercurial's path)
214 214 hgext.mq =
215 215 # (this extension will get loaded from the file specified)
216 216 myfeature = ~/.hgext/myfeature.py
217 217
218 218 format::
219 219
220 220 usestore;;
221 221 Enable or disable the "store" repository format which improves
222 222 compatibility with systems that fold case or otherwise mangle
223 223 filenames. Enabled by default. Disabling this option will allow
224 224 you to store longer filenames in some situations at the expense of
225 225 compatibility.
226 226
227 227 hooks::
228 228 Commands or Python functions that get automatically executed by
229 229 various actions such as starting or finishing a commit. Multiple
230 230 hooks can be run for the same action by appending a suffix to the
231 231 action. Overriding a site-wide hook can be done by changing its
232 232 value or setting it to an empty string.
233 233
234 234 Example .hg/hgrc:
235 235
236 236 [hooks]
237 237 # do not use the site-wide hook
238 238 incoming =
239 239 incoming.email = /my/email/hook
240 240 incoming.autobuild = /my/build/hook
241 241
242 242 Most hooks are run with environment variables set that give added
243 243 useful information. For each hook below, the environment variables
244 244 it is passed are listed with names of the form "$HG_foo".
245 245
246 246 changegroup;;
247 247 Run after a changegroup has been added via push, pull or
248 248 unbundle. ID of the first new changeset is in $HG_NODE. URL from
249 249 which changes came is in $HG_URL.
250 250 commit;;
251 251 Run after a changeset has been created in the local repository.
252 252 ID of the newly created changeset is in $HG_NODE. Parent
253 253 changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
254 254 incoming;;
255 255 Run after a changeset has been pulled, pushed, or unbundled into
256 256 the local repository. The ID of the newly arrived changeset is in
257 257 $HG_NODE. URL that was source of changes came is in $HG_URL.
258 258 outgoing;;
259 259 Run after sending changes from local repository to another. ID of
260 260 first changeset sent is in $HG_NODE. Source of operation is in
261 261 $HG_SOURCE; see "preoutgoing" hook for description.
262 262 prechangegroup;;
263 263 Run before a changegroup is added via push, pull or unbundle.
264 264 Exit status 0 allows the changegroup to proceed. Non-zero status
265 265 will cause the push, pull or unbundle to fail. URL from which
266 266 changes will come is in $HG_URL.
267 267 precommit;;
268 268 Run before starting a local commit. Exit status 0 allows the
269 269 commit to proceed. Non-zero status will cause the commit to fail.
270 270 Parent changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
271 271 preoutgoing;;
272 272 Run before computing changes to send from the local repository to
273 273 another. Non-zero status will cause failure. This lets you
274 274 prevent pull over http or ssh. Also prevents against local pull,
275 275 push (outbound) or bundle commands, but not effective, since you
276 276 can just copy files instead then. Source of operation is in
277 277 $HG_SOURCE. If "serve", operation is happening on behalf of
278 278 remote ssh or http repository. If "push", "pull" or "bundle",
279 279 operation is happening on behalf of repository on same system.
280 280 pretag;;
281 281 Run before creating a tag. Exit status 0 allows the tag to be
282 282 created. Non-zero status will cause the tag to fail. ID of
283 283 changeset to tag is in $HG_NODE. Name of tag is in $HG_TAG. Tag
284 284 is local if $HG_LOCAL=1, in repo if $HG_LOCAL=0.
285 285 pretxnchangegroup;;
286 286 Run after a changegroup has been added via push, pull or unbundle,
287 287 but before the transaction has been committed. Changegroup is
288 288 visible to hook program. This lets you validate incoming changes
289 289 before accepting them. Passed the ID of the first new changeset
290 290 in $HG_NODE. Exit status 0 allows the transaction to commit.
291 291 Non-zero status will cause the transaction to be rolled back and
292 292 the push, pull or unbundle will fail. URL that was source of
293 293 changes is in $HG_URL.
294 294 pretxncommit;;
295 295 Run after a changeset has been created but the transaction not yet
296 296 committed. Changeset is visible to hook program. This lets you
297 297 validate commit message and changes. Exit status 0 allows the
298 298 commit to proceed. Non-zero status will cause the transaction to
299 299 be rolled back. ID of changeset is in $HG_NODE. Parent changeset
300 300 IDs are in $HG_PARENT1 and $HG_PARENT2.
301 301 preupdate;;
302 302 Run before updating the working directory. Exit status 0 allows
303 303 the update to proceed. Non-zero status will prevent the update.
304 304 Changeset ID of first new parent is in $HG_PARENT1. If merge, ID
305 305 of second new parent is in $HG_PARENT2.
306 306 tag;;
307 307 Run after a tag is created. ID of tagged changeset is in
308 308 $HG_NODE. Name of tag is in $HG_TAG. Tag is local if
309 309 $HG_LOCAL=1, in repo if $HG_LOCAL=0.
310 310 update;;
311 311 Run after updating the working directory. Changeset ID of first
312 312 new parent is in $HG_PARENT1. If merge, ID of second new parent
313 313 is in $HG_PARENT2. If update succeeded, $HG_ERROR=0. If update
314 314 failed (e.g. because conflicts not resolved), $HG_ERROR=1.
315 315
316 316 Note: In earlier releases, the names of hook environment variables
317 317 did not have a "HG_" prefix. The old unprefixed names are no longer
318 318 provided in the environment.
319 319
320 320 The syntax for Python hooks is as follows:
321 321
322 322 hookname = python:modulename.submodule.callable
323 323
324 324 Python hooks are run within the Mercurial process. Each hook is
325 325 called with at least three keyword arguments: a ui object (keyword
326 326 "ui"), a repository object (keyword "repo"), and a "hooktype"
327 327 keyword that tells what kind of hook is used. Arguments listed as
328 328 environment variables above are passed as keyword arguments, with no
329 329 "HG_" prefix, and names in lower case.
330 330
331 331 If a Python hook returns a "true" value or raises an exception, this
332 332 is treated as failure of the hook.
333 333
334 334 http_proxy::
335 335 Used to access web-based Mercurial repositories through a HTTP
336 336 proxy.
337 337 host;;
338 338 Host name and (optional) port of the proxy server, for example
339 339 "myproxy:8000".
340 340 no;;
341 341 Optional. Comma-separated list of host names that should bypass
342 342 the proxy.
343 343 passwd;;
344 344 Optional. Password to authenticate with at the proxy server.
345 345 user;;
346 346 Optional. User name to authenticate with at the proxy server.
347 347
348 348 smtp::
349 349 Configuration for extensions that need to send email messages.
350 350 host;;
351 351 Host name of mail server, e.g. "mail.example.com".
352 352 port;;
353 353 Optional. Port to connect to on mail server. Default: 25.
354 354 tls;;
355 355 Optional. Whether to connect to mail server using TLS. True or
356 356 False. Default: False.
357 357 username;;
358 358 Optional. User name to authenticate to SMTP server with.
359 359 If username is specified, password must also be specified.
360 360 Default: none.
361 361 password;;
362 362 Optional. Password to authenticate to SMTP server with.
363 363 If username is specified, password must also be specified.
364 364 Default: none.
365 365 local_hostname;;
366 366 Optional. It's the hostname that the sender can use to identify itself
367 367 to the MTA.
368 368
369 369 paths::
370 370 Assigns symbolic names to repositories. The left side is the
371 371 symbolic name, and the right gives the directory or URL that is the
372 372 location of the repository. Default paths can be declared by
373 373 setting the following entries.
374 374 default;;
375 375 Directory or URL to use when pulling if no source is specified.
376 376 Default is set to repository from which the current repository
377 377 was cloned.
378 378 default-push;;
379 379 Optional. Directory or URL to use when pushing if no destination
380 380 is specified.
381 381
382 382 server::
383 383 Controls generic server settings.
384 384 uncompressed;;
385 385 Whether to allow clients to clone a repo using the uncompressed
386 386 streaming protocol. This transfers about 40% more data than a
387 387 regular clone, but uses less memory and CPU on both server and
388 388 client. Over a LAN (100Mbps or better) or a very fast WAN, an
389 389 uncompressed streaming clone is a lot faster (~10x) than a regular
390 390 clone. Over most WAN connections (anything slower than about
391 391 6Mbps), uncompressed streaming is slower, because of the extra
392 392 data transfer overhead. Default is False.
393 393
394 394 trusted::
395 395 For security reasons, Mercurial will not use the settings in
396 396 the .hg/hgrc file from a repository if it doesn't belong to a
397 397 trusted user or to a trusted group. The main exception is the
398 398 web interface, which automatically uses some safe settings, since
399 399 it's common to serve repositories from different users.
400 400
401 401 This section specifies what users and groups are trusted. The
402 402 current user is always trusted. To trust everybody, list a user
403 403 or a group with name "*".
404 404
405 405 users;;
406 406 Comma-separated list of trusted users.
407 407 groups;;
408 408 Comma-separated list of trusted groups.
409 409
410 410 ui::
411 411 User interface controls.
412 412 debug;;
413 413 Print debugging information. True or False. Default is False.
414 414 editor;;
415 415 The editor to use during a commit. Default is $EDITOR or "vi".
416 416 fallbackencoding;;
417 417 Encoding to try if it's not possible to decode the changelog using
418 418 UTF-8. Default is ISO-8859-1.
419 419 ignore;;
420 420 A file to read per-user ignore patterns from. This file should be in
421 421 the same format as a repository-wide .hgignore file. This option
422 422 supports hook syntax, so if you want to specify multiple ignore
423 423 files, you can do so by setting something like
424 424 "ignore.other = ~/.hgignore2". For details of the ignore file
425 425 format, see the hgignore(5) man page.
426 426 interactive;;
427 427 Allow to prompt the user. True or False. Default is True.
428 428 logtemplate;;
429 429 Template string for commands that print changesets.
430 430 style;;
431 431 Name of style to use for command output.
432 432 merge;;
433 433 The conflict resolution program to use during a manual merge.
434 434 Default is "hgmerge".
435 435 patch;;
436 436 command to use to apply patches. Look for 'gpatch' or 'patch' in PATH if
437 437 unset.
438 438 quiet;;
439 439 Reduce the amount of output printed. True or False. Default is False.
440 440 remotecmd;;
441 441 remote command to use for clone/push/pull operations. Default is 'hg'.
442 slash;;
443 Display paths using a slash ("/") as the path separator. This only
444 makes a difference on systems where the default path separator is not
445 the slash character (e.g. Windows uses the backslash character ("\")).
446 Default is False.
442 447 ssh;;
443 448 command to use for SSH connections. Default is 'ssh'.
444 449 strict;;
445 450 Require exact command names, instead of allowing unambiguous
446 451 abbreviations. True or False. Default is False.
447 452 timeout;;
448 453 The timeout used when a lock is held (in seconds), a negative value
449 454 means no timeout. Default is 600.
450 455 username;;
451 456 The committer of a changeset created when running "commit".
452 457 Typically a person's name and email address, e.g. "Fred Widget
453 458 <fred@example.com>". Default is $EMAIL or username@hostname.
454 459 If the username in hgrc is empty, it has to be specified manually or
455 460 in a different hgrc file (e.g. $HOME/.hgrc, if the admin set "username ="
456 461 in the system hgrc).
457 462 verbose;;
458 463 Increase the amount of output printed. True or False. Default is False.
459 464
460 465
461 466 web::
462 467 Web interface configuration.
463 468 accesslog;;
464 469 Where to output the access log. Default is stdout.
465 470 address;;
466 471 Interface address to bind to. Default is all.
467 472 allow_archive;;
468 473 List of archive format (bz2, gz, zip) allowed for downloading.
469 474 Default is empty.
470 475 allowbz2;;
471 476 (DEPRECATED) Whether to allow .tar.bz2 downloading of repo revisions.
472 477 Default is false.
473 478 allowgz;;
474 479 (DEPRECATED) Whether to allow .tar.gz downloading of repo revisions.
475 480 Default is false.
476 481 allowpull;;
477 482 Whether to allow pulling from the repository. Default is true.
478 483 allow_push;;
479 484 Whether to allow pushing to the repository. If empty or not set,
480 485 push is not allowed. If the special value "*", any remote user
481 486 can push, including unauthenticated users. Otherwise, the remote
482 487 user must have been authenticated, and the authenticated user name
483 488 must be present in this list (separated by whitespace or ",").
484 489 The contents of the allow_push list are examined after the
485 490 deny_push list.
486 491 allowzip;;
487 492 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
488 493 Default is false. This feature creates temporary files.
489 494 baseurl;;
490 495 Base URL to use when publishing URLs in other locations, so
491 496 third-party tools like email notification hooks can construct URLs.
492 497 Example: "http://hgserver/repos/"
493 498 contact;;
494 499 Name or email address of the person in charge of the repository.
495 500 Default is "unknown".
496 501 deny_push;;
497 502 Whether to deny pushing to the repository. If empty or not set,
498 503 push is not denied. If the special value "*", all remote users
499 504 are denied push. Otherwise, unauthenticated users are all denied,
500 505 and any authenticated user name present in this list (separated by
501 506 whitespace or ",") is also denied. The contents of the deny_push
502 507 list are examined before the allow_push list.
503 508 description;;
504 509 Textual description of the repository's purpose or contents.
505 510 Default is "unknown".
506 511 errorlog;;
507 512 Where to output the error log. Default is stderr.
508 513 ipv6;;
509 514 Whether to use IPv6. Default is false.
510 515 name;;
511 516 Repository name to use in the web interface. Default is current
512 517 working directory.
513 518 maxchanges;;
514 519 Maximum number of changes to list on the changelog. Default is 10.
515 520 maxfiles;;
516 521 Maximum number of files to list per changeset. Default is 10.
517 522 port;;
518 523 Port to listen on. Default is 8000.
519 524 push_ssl;;
520 525 Whether to require that inbound pushes be transported over SSL to
521 526 prevent password sniffing. Default is true.
522 527 staticurl;;
523 528 Base URL to use for static files. If unset, static files (e.g.
524 529 the hgicon.png favicon) will be served by the CGI script itself.
525 530 Use this setting to serve them directly with the HTTP server.
526 531 Example: "http://hgserver/static/"
527 532 stripes;;
528 533 How many lines a "zebra stripe" should span in multiline output.
529 534 Default is 1; set to 0 to disable.
530 535 style;;
531 536 Which template map style to use.
532 537 templates;;
533 538 Where to find the HTML templates. Default is install path.
534 539
535 540
536 541 AUTHOR
537 542 ------
538 543 Bryan O'Sullivan <bos@serpentine.com>.
539 544
540 545 Mercurial was written by Matt Mackall <mpm@selenic.com>.
541 546
542 547 SEE ALSO
543 548 --------
544 549 hg(1), hgignore(5)
545 550
546 551 COPYING
547 552 -------
548 553 This manual page is copyright 2005 Bryan O'Sullivan.
549 554 Mercurial is copyright 2005, 2006 Matt Mackall.
550 555 Free use of this software is granted under the terms of the GNU General
551 556 Public License (GPL).
@@ -1,596 +1,602
1 1 """
2 2 dirstate.py - working directory tracking for mercurial
3 3
4 4 Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
5 5
6 6 This software may be used and distributed according to the terms
7 7 of the GNU General Public License, incorporated herein by reference.
8 8 """
9 9
10 10 from node import *
11 11 from i18n import _
12 12 import struct, os, time, bisect, stat, strutil, util, re, errno
13 13 import cStringIO
14 14
15 15 class dirstate(object):
16 16 format = ">cllll"
17 17
18 18 def __init__(self, opener, ui, root):
19 19 self.opener = opener
20 20 self.root = root
21 21 self.dirty = 0
22 22 self.ui = ui
23 23 self.map = None
24 24 self.fp = None
25 25 self.pl = None
26 26 self.dirs = None
27 27 self.copymap = {}
28 28 self.ignorefunc = None
29 29 self._branch = None
30 self._slash = None
30 31
31 32 def wjoin(self, f):
32 33 return os.path.join(self.root, f)
33 34
34 35 def getcwd(self):
35 36 cwd = os.getcwd()
36 37 if cwd == self.root: return ''
37 38 # self.root ends with a path separator if self.root is '/' or 'C:\'
38 39 rootsep = self.root
39 40 if not rootsep.endswith(os.sep):
40 41 rootsep += os.sep
41 42 if cwd.startswith(rootsep):
42 43 return cwd[len(rootsep):]
43 44 else:
44 45 # we're outside the repo. return an absolute path.
45 46 return cwd
46 47
47 48 def pathto(self, f, cwd=None):
48 49 if cwd is None:
49 50 cwd = self.getcwd()
50 return util.pathto(self.root, cwd, f)
51 path = util.pathto(self.root, cwd, f)
52 if self._slash is None:
53 self._slash = self.ui.configbool('ui', 'slash') and os.sep != '/'
54 if self._slash:
55 path = path.replace(os.sep, '/')
56 return path
51 57
52 58 def hgignore(self):
53 59 '''return the contents of .hgignore files as a list of patterns.
54 60
55 61 the files parsed for patterns include:
56 62 .hgignore in the repository root
57 63 any additional files specified in the [ui] section of ~/.hgrc
58 64
59 65 trailing white space is dropped.
60 66 the escape character is backslash.
61 67 comments start with #.
62 68 empty lines are skipped.
63 69
64 70 lines can be of the following formats:
65 71
66 72 syntax: regexp # defaults following lines to non-rooted regexps
67 73 syntax: glob # defaults following lines to non-rooted globs
68 74 re:pattern # non-rooted regular expression
69 75 glob:pattern # non-rooted glob
70 76 pattern # pattern of the current default type'''
71 77 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
72 78 def parselines(fp):
73 79 for line in fp:
74 80 if not line.endswith('\n'):
75 81 line += '\n'
76 82 escape = False
77 83 for i in xrange(len(line)):
78 84 if escape: escape = False
79 85 elif line[i] == '\\': escape = True
80 86 elif line[i] == '#': break
81 87 line = line[:i].rstrip()
82 88 if line: yield line
83 89 repoignore = self.wjoin('.hgignore')
84 90 files = [repoignore]
85 91 files.extend(self.ui.hgignorefiles())
86 92 pats = {}
87 93 for f in files:
88 94 try:
89 95 pats[f] = []
90 96 fp = open(f)
91 97 syntax = 'relre:'
92 98 for line in parselines(fp):
93 99 if line.startswith('syntax:'):
94 100 s = line[7:].strip()
95 101 try:
96 102 syntax = syntaxes[s]
97 103 except KeyError:
98 104 self.ui.warn(_("%s: ignoring invalid "
99 105 "syntax '%s'\n") % (f, s))
100 106 continue
101 107 pat = syntax + line
102 108 for s in syntaxes.values():
103 109 if line.startswith(s):
104 110 pat = line
105 111 break
106 112 pats[f].append(pat)
107 113 except IOError, inst:
108 114 if f != repoignore:
109 115 self.ui.warn(_("skipping unreadable ignore file"
110 116 " '%s': %s\n") % (f, inst.strerror))
111 117 return pats
112 118
113 119 def ignore(self, fn):
114 120 '''default match function used by dirstate and
115 121 localrepository. this honours the repository .hgignore file
116 122 and any other files specified in the [ui] section of .hgrc.'''
117 123 if not self.ignorefunc:
118 124 ignore = self.hgignore()
119 125 allpats = []
120 126 [allpats.extend(patlist) for patlist in ignore.values()]
121 127 if allpats:
122 128 try:
123 129 files, self.ignorefunc, anypats = (
124 130 util.matcher(self.root, inc=allpats, src='.hgignore'))
125 131 except util.Abort:
126 132 # Re-raise an exception where the src is the right file
127 133 for f, patlist in ignore.items():
128 134 files, self.ignorefunc, anypats = (
129 135 util.matcher(self.root, inc=patlist, src=f))
130 136 else:
131 137 self.ignorefunc = util.never
132 138 return self.ignorefunc(fn)
133 139
134 140 def __del__(self):
135 141 if self.dirty:
136 142 self.write()
137 143
138 144 def __getitem__(self, key):
139 145 try:
140 146 return self.map[key]
141 147 except TypeError:
142 148 self.lazyread()
143 149 return self[key]
144 150
145 151 _unknown = ('?', 0, 0, 0)
146 152
147 153 def get(self, key):
148 154 try:
149 155 return self[key]
150 156 except KeyError:
151 157 return self._unknown
152 158
153 159 def __contains__(self, key):
154 160 self.lazyread()
155 161 return key in self.map
156 162
157 163 def parents(self):
158 164 if self.pl is None:
159 165 self.pl = [nullid, nullid]
160 166 try:
161 167 self.fp = self.opener('dirstate')
162 168 st = self.fp.read(40)
163 169 if len(st) == 40:
164 170 self.pl = st[:20], st[20:40]
165 171 except IOError, err:
166 172 if err.errno != errno.ENOENT: raise
167 173 return self.pl
168 174
169 175 def branch(self):
170 176 if not self._branch:
171 177 try:
172 178 self._branch = self.opener("branch").read().strip()\
173 179 or "default"
174 180 except IOError:
175 181 self._branch = "default"
176 182 return self._branch
177 183
178 184 def markdirty(self):
179 185 if not self.dirty:
180 186 self.dirty = 1
181 187
182 188 def setparents(self, p1, p2=nullid):
183 189 self.lazyread()
184 190 self.markdirty()
185 191 self.pl = p1, p2
186 192
187 193 def setbranch(self, branch):
188 194 self._branch = branch
189 195 self.opener("branch", "w").write(branch + '\n')
190 196
191 197 def state(self, key):
192 198 try:
193 199 return self[key][0]
194 200 except KeyError:
195 201 return "?"
196 202
197 203 def lazyread(self):
198 204 if self.map is None:
199 205 self.read()
200 206
201 207 def parse(self, st):
202 208 self.pl = [st[:20], st[20: 40]]
203 209
204 210 # deref fields so they will be local in loop
205 211 map = self.map
206 212 copymap = self.copymap
207 213 format = self.format
208 214 unpack = struct.unpack
209 215
210 216 pos = 40
211 217 e_size = struct.calcsize(format)
212 218
213 219 while pos < len(st):
214 220 newpos = pos + e_size
215 221 e = unpack(format, st[pos:newpos])
216 222 l = e[4]
217 223 pos = newpos
218 224 newpos = pos + l
219 225 f = st[pos:newpos]
220 226 if '\0' in f:
221 227 f, c = f.split('\0')
222 228 copymap[f] = c
223 229 map[f] = e[:4]
224 230 pos = newpos
225 231
226 232 def read(self):
227 233 self.map = {}
228 234 self.pl = [nullid, nullid]
229 235 try:
230 236 if self.fp:
231 237 self.fp.seek(0)
232 238 st = self.fp.read()
233 239 self.fp = None
234 240 else:
235 241 st = self.opener("dirstate").read()
236 242 if st:
237 243 self.parse(st)
238 244 except IOError, err:
239 245 if err.errno != errno.ENOENT: raise
240 246
241 247 def reload(self):
242 248 def mtime():
243 249 m = self.map and self.map.get('.hgignore')
244 250 return m and m[-1]
245 251
246 252 old_mtime = self.ignorefunc and mtime()
247 253 self.read()
248 254 if old_mtime != mtime():
249 255 self.ignorefunc = None
250 256
251 257 def copy(self, source, dest):
252 258 self.lazyread()
253 259 self.markdirty()
254 260 self.copymap[dest] = source
255 261
256 262 def copied(self, file):
257 263 return self.copymap.get(file, None)
258 264
259 265 def copies(self):
260 266 return self.copymap
261 267
262 268 def initdirs(self):
263 269 if self.dirs is None:
264 270 self.dirs = {}
265 271 for f in self.map:
266 272 self.updatedirs(f, 1)
267 273
268 274 def updatedirs(self, path, delta):
269 275 if self.dirs is not None:
270 276 for c in strutil.findall(path, '/'):
271 277 pc = path[:c]
272 278 self.dirs.setdefault(pc, 0)
273 279 self.dirs[pc] += delta
274 280
275 281 def checkinterfering(self, files):
276 282 def prefixes(f):
277 283 for c in strutil.rfindall(f, '/'):
278 284 yield f[:c]
279 285 self.lazyread()
280 286 self.initdirs()
281 287 seendirs = {}
282 288 for f in files:
283 289 # shadows
284 290 if self.dirs.get(f):
285 291 raise util.Abort(_('directory named %r already in dirstate') %
286 292 f)
287 293 for d in prefixes(f):
288 294 if d in seendirs:
289 295 break
290 296 if d in self.map:
291 297 raise util.Abort(_('file named %r already in dirstate') %
292 298 d)
293 299 seendirs[d] = True
294 300 # disallowed
295 301 if '\r' in f or '\n' in f:
296 302 raise util.Abort(_("'\\n' and '\\r' disallowed in filenames"))
297 303
298 304 def update(self, files, state, **kw):
299 305 ''' current states:
300 306 n normal
301 307 m needs merging
302 308 r marked for removal
303 309 a marked for addition'''
304 310
305 311 if not files: return
306 312 self.lazyread()
307 313 self.markdirty()
308 314 if state == "a":
309 315 self.initdirs()
310 316 self.checkinterfering(files)
311 317 for f in files:
312 318 if state == "r":
313 319 self.map[f] = ('r', 0, 0, 0)
314 320 self.updatedirs(f, -1)
315 321 else:
316 322 if state == "a":
317 323 self.updatedirs(f, 1)
318 324 s = os.lstat(self.wjoin(f))
319 325 st_size = kw.get('st_size', s.st_size)
320 326 st_mtime = kw.get('st_mtime', s.st_mtime)
321 327 self.map[f] = (state, s.st_mode, st_size, st_mtime)
322 328 if self.copymap.has_key(f):
323 329 del self.copymap[f]
324 330
325 331 def forget(self, files):
326 332 if not files: return
327 333 self.lazyread()
328 334 self.markdirty()
329 335 self.initdirs()
330 336 for f in files:
331 337 try:
332 338 del self.map[f]
333 339 self.updatedirs(f, -1)
334 340 except KeyError:
335 341 self.ui.warn(_("not in dirstate: %s!\n") % f)
336 342 pass
337 343
338 344 def clear(self):
339 345 self.map = {}
340 346 self.copymap = {}
341 347 self.dirs = None
342 348 self.markdirty()
343 349
344 350 def rebuild(self, parent, files):
345 351 self.clear()
346 352 for f in files:
347 353 if files.execf(f):
348 354 self.map[f] = ('n', 0777, -1, 0)
349 355 else:
350 356 self.map[f] = ('n', 0666, -1, 0)
351 357 self.pl = (parent, nullid)
352 358 self.markdirty()
353 359
354 360 def write(self):
355 361 if not self.dirty:
356 362 return
357 363 cs = cStringIO.StringIO()
358 364 cs.write("".join(self.pl))
359 365 for f, e in self.map.iteritems():
360 366 c = self.copied(f)
361 367 if c:
362 368 f = f + "\0" + c
363 369 e = struct.pack(self.format, e[0], e[1], e[2], e[3], len(f))
364 370 cs.write(e)
365 371 cs.write(f)
366 372 st = self.opener("dirstate", "w", atomictemp=True)
367 373 st.write(cs.getvalue())
368 374 st.rename()
369 375 self.dirty = 0
370 376
371 377 def filterfiles(self, files):
372 378 ret = {}
373 379 unknown = []
374 380
375 381 for x in files:
376 382 if x == '.':
377 383 return self.map.copy()
378 384 if x not in self.map:
379 385 unknown.append(x)
380 386 else:
381 387 ret[x] = self.map[x]
382 388
383 389 if not unknown:
384 390 return ret
385 391
386 392 b = self.map.keys()
387 393 b.sort()
388 394 blen = len(b)
389 395
390 396 for x in unknown:
391 397 bs = bisect.bisect(b, "%s%s" % (x, '/'))
392 398 while bs < blen:
393 399 s = b[bs]
394 400 if len(s) > len(x) and s.startswith(x):
395 401 ret[s] = self.map[s]
396 402 else:
397 403 break
398 404 bs += 1
399 405 return ret
400 406
401 407 def supported_type(self, f, st, verbose=False):
402 408 if stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode):
403 409 return True
404 410 if verbose:
405 411 kind = 'unknown'
406 412 if stat.S_ISCHR(st.st_mode): kind = _('character device')
407 413 elif stat.S_ISBLK(st.st_mode): kind = _('block device')
408 414 elif stat.S_ISFIFO(st.st_mode): kind = _('fifo')
409 415 elif stat.S_ISSOCK(st.st_mode): kind = _('socket')
410 416 elif stat.S_ISDIR(st.st_mode): kind = _('directory')
411 417 self.ui.warn(_('%s: unsupported file type (type is %s)\n')
412 418 % (self.pathto(f), kind))
413 419 return False
414 420
415 421 def walk(self, files=None, match=util.always, badmatch=None):
416 422 # filter out the stat
417 423 for src, f, st in self.statwalk(files, match, badmatch=badmatch):
418 424 yield src, f
419 425
420 426 def statwalk(self, files=None, match=util.always, ignored=False,
421 427 badmatch=None, directories=False):
422 428 '''
423 429 walk recursively through the directory tree, finding all files
424 430 matched by the match function
425 431
426 432 results are yielded in a tuple (src, filename, st), where src
427 433 is one of:
428 434 'f' the file was found in the directory tree
429 435 'd' the file is a directory of the tree
430 436 'm' the file was only in the dirstate and not in the tree
431 437 'b' file was not found and matched badmatch
432 438
433 439 and st is the stat result if the file was found in the directory.
434 440 '''
435 441 self.lazyread()
436 442
437 443 # walk all files by default
438 444 if not files:
439 445 files = ['.']
440 446 dc = self.map.copy()
441 447 else:
442 448 files = util.unique(files)
443 449 dc = self.filterfiles(files)
444 450
445 451 def imatch(file_):
446 452 if file_ not in dc and self.ignore(file_):
447 453 return False
448 454 return match(file_)
449 455
450 456 ignore = self.ignore
451 457 if ignored:
452 458 imatch = match
453 459 ignore = util.never
454 460
455 461 # self.root may end with a path separator when self.root == '/'
456 462 common_prefix_len = len(self.root)
457 463 if not self.root.endswith(os.sep):
458 464 common_prefix_len += 1
459 465 # recursion free walker, faster than os.walk.
460 466 def findfiles(s):
461 467 work = [s]
462 468 if directories:
463 469 yield 'd', util.normpath(s[common_prefix_len:]), os.lstat(s)
464 470 while work:
465 471 top = work.pop()
466 472 names = os.listdir(top)
467 473 names.sort()
468 474 # nd is the top of the repository dir tree
469 475 nd = util.normpath(top[common_prefix_len:])
470 476 if nd == '.':
471 477 nd = ''
472 478 else:
473 479 # do not recurse into a repo contained in this
474 480 # one. use bisect to find .hg directory so speed
475 481 # is good on big directory.
476 482 hg = bisect.bisect_left(names, '.hg')
477 483 if hg < len(names) and names[hg] == '.hg':
478 484 if os.path.isdir(os.path.join(top, '.hg')):
479 485 continue
480 486 for f in names:
481 487 np = util.pconvert(os.path.join(nd, f))
482 488 if seen(np):
483 489 continue
484 490 p = os.path.join(top, f)
485 491 # don't trip over symlinks
486 492 st = os.lstat(p)
487 493 if stat.S_ISDIR(st.st_mode):
488 494 if not ignore(np):
489 495 work.append(p)
490 496 if directories:
491 497 yield 'd', np, st
492 498 if imatch(np) and np in dc:
493 499 yield 'm', np, st
494 500 elif imatch(np):
495 501 if self.supported_type(np, st):
496 502 yield 'f', np, st
497 503 elif np in dc:
498 504 yield 'm', np, st
499 505
500 506 known = {'.hg': 1}
501 507 def seen(fn):
502 508 if fn in known: return True
503 509 known[fn] = 1
504 510
505 511 # step one, find all files that match our criteria
506 512 files.sort()
507 513 for ff in files:
508 514 nf = util.normpath(ff)
509 515 f = self.wjoin(ff)
510 516 try:
511 517 st = os.lstat(f)
512 518 except OSError, inst:
513 519 found = False
514 520 for fn in dc:
515 521 if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
516 522 found = True
517 523 break
518 524 if not found:
519 525 if inst.errno != errno.ENOENT or not badmatch:
520 526 self.ui.warn('%s: %s\n' % (self.pathto(ff),
521 527 inst.strerror))
522 528 elif badmatch and badmatch(ff) and imatch(nf):
523 529 yield 'b', ff, None
524 530 continue
525 531 if stat.S_ISDIR(st.st_mode):
526 532 cmp1 = (lambda x, y: cmp(x[1], y[1]))
527 533 sorted_ = [ x for x in findfiles(f) ]
528 534 sorted_.sort(cmp1)
529 535 for e in sorted_:
530 536 yield e
531 537 else:
532 538 if not seen(nf) and match(nf):
533 539 if self.supported_type(ff, st, verbose=True):
534 540 yield 'f', nf, st
535 541 elif ff in dc:
536 542 yield 'm', nf, st
537 543
538 544 # step two run through anything left in the dc hash and yield
539 545 # if we haven't already seen it
540 546 ks = dc.keys()
541 547 ks.sort()
542 548 for k in ks:
543 549 if not seen(k) and imatch(k):
544 550 yield 'm', k, None
545 551
546 552 def status(self, files=None, match=util.always, list_ignored=False,
547 553 list_clean=False):
548 554 lookup, modified, added, unknown, ignored = [], [], [], [], []
549 555 removed, deleted, clean = [], [], []
550 556
551 557 for src, fn, st in self.statwalk(files, match, ignored=list_ignored):
552 558 try:
553 559 type_, mode, size, time = self[fn]
554 560 except KeyError:
555 561 if list_ignored and self.ignore(fn):
556 562 ignored.append(fn)
557 563 else:
558 564 unknown.append(fn)
559 565 continue
560 566 if src == 'm':
561 567 nonexistent = True
562 568 if not st:
563 569 try:
564 570 st = os.lstat(self.wjoin(fn))
565 571 except OSError, inst:
566 572 if inst.errno != errno.ENOENT:
567 573 raise
568 574 st = None
569 575 # We need to re-check that it is a valid file
570 576 if st and self.supported_type(fn, st):
571 577 nonexistent = False
572 578 # XXX: what to do with file no longer present in the fs
573 579 # who are not removed in the dirstate ?
574 580 if nonexistent and type_ in "nm":
575 581 deleted.append(fn)
576 582 continue
577 583 # check the common case first
578 584 if type_ == 'n':
579 585 if not st:
580 586 st = os.lstat(self.wjoin(fn))
581 587 if size >= 0 and (size != st.st_size
582 588 or (mode ^ st.st_mode) & 0100):
583 589 modified.append(fn)
584 590 elif time != int(st.st_mtime):
585 591 lookup.append(fn)
586 592 elif list_clean:
587 593 clean.append(fn)
588 594 elif type_ == 'm':
589 595 modified.append(fn)
590 596 elif type_ == 'a':
591 597 added.append(fn)
592 598 elif type_ == 'r':
593 599 removed.append(fn)
594 600
595 601 return (lookup, modified, added, removed, deleted, unknown, ignored,
596 602 clean)
General Comments 0
You need to be logged in to leave comments. Login now