Moves ssh argument building to platform specific utils code.
The win32 version looks for plink in ssh command string and
uses '-P' in lieu of '-p' for specifying a port
Allow adding to dirstate files that clash with previously existing
but marked for removal. Protect from reintroducing clashes by revert.
This change doesn't address related issues with update. Current
workaround is to do "clean" update by manually removing conflicting
files/dirs from working directory.
commit (aborts _after_ typing in a commit message)
backout (aborted after the initial revert)
tag (edited .hgtags and couldn't commit)
import (patch applied, then commit fails)
qnew (aborts on bad dates, but writes any valid date into the # Date header)
qrefresh (like qnew)
sign (like tag)
fetch (merge, merge, merge, merge, abort)
This could happen e.g. in group writable local repositories where a file
should become executable on update.
(Patch by Benoit Boissinot attached to issue530)
On Linux VFAT execution mode can be modified, but changes don't
persist a filesy stem remount. The current test can be trickled by
this. We can help with the det ection of VFAT checking whether new
files get created with the execution bits on
(as usually these partitions are mounted with the exec option, for
convenience)
.
We use a separate cache to avoid problems with
audit = path_auditor(repo.root)
audit("subrepo")
audit("subrepo/file")
whitelisting "subrepo" (which is fine) and then using the same whitelist
with "subrepo/file" (which is not fine).
Since we create a separate path_auditor for every path on the command line,
a "hg add dir/a dir/b dir/c" will still lstat dir 3 times just to audit
the paths.
The following properties of a path are now checked for:
- under top-level .hg
- starts at the root of a windows drive
- contains ".."
- traverses a symlink (e.g. a/symlink_here/b)
- inside a nested repository
If any of these is true, the path is rejected.
The check for traversing a symlink is arguably stricter than necessary;
perhaps we should be checking for symlinks that point outside the
repository.
Simply use find_exe('hg') as the default value for $HG and require to manually
set it if you have special requirements.
While the default will not always be 100% correct (i.e. the identical hg
version) for many users it is and for the others the hg executable found in
the PATH should do most things correctly.
Developers or other users with multiple installs can set $HG or run something
like util.set_hgexecutable in their shell or python scripts.
Additionally util.hgexecutable() is now available so extensions can access
the value with a public interface, too.
Differences from os.symlink:
- the symlink name is relative to the opener base directory
- if a file with that name already exists, it's removed
- if necessary, parent directories are created
- if the system (OS or filesystem) doesn't support symlinks, a
regular file is created. Its contents are the symlink target.
The original idea might have been to prevent circular references, but
as this assignment would have created another reference, this makes
no difference.
In python 2.4+ on darwin, locale.getpreferredencoding() returns
mac-roman regardless of what LC_CTYPE, LANG etc are set to. This can
produce hard-to-notice conversion errors if input text is not in
mac-roman. So this patch overrides it with setlocale/getlocale if the
environment has been customized, on the assumption that the user has
done so deliberately.
The interface provided by opener(atomic=True) is inherently unsafe:
if an exception is raised in the code using the atomic file, the
possibly incomplete file will be renamed to its final destination,
defeating the whole purpose of atomic files.
To get around this, we would either need some bad hacks involving
sys.exc_info (to make sure things work in except: blocks), or an
interface to say "file is complete; rename it".
This is the exact interface provided by atomictempfile. Since there
are no remaining users of the atomicfile class, just remove it.
The behaviour of find_in_path was broken for config options containing
path names, because it always searched the given path, even when not
necessary. The find_exe function is more polite: if the name passed
to it contains a path component, it just returns it.
In cdc7e3627e1b, Benoit made a change that substantially slows matching
when a big .hgignore file is in play, because it calls into the regexp
matching engine potentially hundreds of times per file to be matched.
I've partly rolled back his change, so that we only call into the matcher
once per file, but preserved the ability to report a meaningful error
message if there's a syntax error in the regexp.
Right now, surprisingly enough, if you request an atomic file but the
file still doesn't exist, you get a regular file. AFAICS, the only time
this happens is during the initial creation of the dirstate.
With this change, you have to use "hg locate 'hgweb/**'" to locate
all the files in directories named hgweb. OTOH, "hg locate '*l'"
will locate only files that end with "l" - e.g. a file called "hg.py"
will not be matched just because it's in a directory whose name ends
with "l" (e.g. "mercurial").
With that changeset, it's impossible to use a glob: pattern to match
e.g. all files ending in .py - glob:**.py would also match all files
in a directory called dir.py.
This makes the behaviour of glob: patterns more consistent:
hg status glob:dir and hg status -I glob:dir will match
the same files.
It's also consistent with the fact that {rel,}path patterns
recursively match the contents of a directory.
This will trigger every time somebody runs something like "hg diff"
or "hg status" without any arguments.
The important part here is returning util.always as the match function,
which is a much simpler (and faster) function than the usual return
value, and allows other code to just skip the filtering if it knows
all files will match.
This makes its default behaviour useful again (issue108), and
changes it search the entire repository by default (instead
of just the cwd), just like all other commands.
It also hides issue204 by default, but you'll still see the
same behaviour if you give it a relpath: pattern.
This removes a hack where we appended '/' to a dirname so that:
- it would not appear on the "dc" dict
- it would always be matched by the match function
This was a contorted way of checking if the directory was matched by
some hgignore pattern, and it would still fail with some uses of
--include/--exclude patterns.
Things would still work fine if we removed the check altogether and
just appended things to "work" directly, but then we would end up
walking ignored directories too, which could be quite a bit of work.
This allows further simplification of the match function returned by
util._matcher, and fixes walking the working directory with a
--include pattern that matches only the end of a name.
This should fix issue347.
It also highlights one issue with the directory walking code when
you have an --include pattern that matches the end of a filename.
This is fixed by the next patch.
names=['.'] means "include (recursively) only files from the current subdir";
the function then did a hack to walk the whole tree. Clean that up.
This also fixes a problem where "--include ." works in a subdir, but not
on the tree root.
The main problem was that dirstate.getcwd() returned just "",
which was interpreted as "we're at the repo root". It now returns
an absolute path.
The util.pathto function was also changed to deal with the "cwd is
an absolute path" case.
Changed os_rcpath to combine system_rcpath and user_rcpath. Changed
system_rcpath and user_rcpath to both return a list of paths to add to the
combined rcpath for both Windows NT and other platforms.
Add extended date formats (eg "Dec", "2006")
Add a couple missing basic date formats
Improve default date element scheme to parsedate
Add matchdate function to match a date spec
Add -e switch and range matching to debugdate
The list of trusted users and groups is specified in the [trusted]
section of a hgrc; the current user is always trusted; "*" can be
used to trust all users/groups.
Global hgrc files are always read.
On Windows (and other systems that don't have the pwd and grp modules),
all .hg/hgrc files are read.
This is essentially the same patch that was previously applied as
revision f077d29b114d.
This change has the potential to break existing setups, but the current
behaviour (the keys in configuration files are always lower-cased) can
bite us in a few places:
- no way to use a Command in [defaults]
- hgext.Extension doesn't work in [extensions]
- you can't use an Upper/case/PATH in the [paths] section of hgweb.config
- you can't (easily) protect paths with upper-case letters with the
acl extension
- you can't specify a /Path/TO/a/rEPO in the [reposubs] section for
the notify extension
Vanilla patch chokes on git patches that include files that are copied
or renamed, then modified. So this code detects that case and rewrites
the patch if necessary.
existing clone code uses pull to get changes from remote repo. is very
slow, uses lots of memory and cpu.
new clone code has server write file data straight to client, client
writes file data straight to disk. memory and cpu used are very low,
clone is much faster over lan.
new client can still clone with pull, can still clone from older servers.
new server can still serve older clients.
str.find return -1 when the substring is not found, -1 evaluate
to True and is a valid index, which can lead to bugs.
Using alternatives when possible makes the code clearer and less
prone to bugs. (and __contains__ is faster in microbenchmarks)
When the gpatch fix for solaris was introduced in b67447b909f3 the
patch command was "". For some strange reason windows 2000 is
not happy with those quotes when given in os.popen.
This hides the following traceback (there's a race condition involved,
so you may have to try a few times to hit it):
$ hg sign --key key-that-does-not-exist
Signing 2062:4bad92f4ea65
gpg: skipped "key-that-does-not-exist": secret key not available
gpg: signing failed: secret key not available
Exception in thread Thread-1:
Traceback (most recent call last):
File "threading.py", line 442, in __bootstrap
self.run()
File "threading.py", line 422, in run
self.__target(*self.__args, **self.__kwargs)
File "mercurial/util.py", line 24, in writer
pin.close()
IOError: [Errno 32] Broken pipe
abort: Error while signing
The revlog.checkinlinesize() uses an atomic opener to replace the
index file after converting it from inline to traditional .i and .d
files. If this operation is interrupted, the atomic file class can
overwrite a valid file with a partially written one.
This patch introduces an atomic opener that does not automatically
replace the destination file with the tempfile. This way
an interrupted checkinlinesize() call turns into a noop.
Handle processes that no longer exist and processes that belong to another user.
Enables the lock breaking changes from 0ab4c12ad060 and subsequently "fixes" the left over locks reported in bug 112.
to use, "hg log --style=changelog". makes different output with no
flags, -q, -v, --debug.
templater module has new template filters for this.
email - committer email address
fill68 - refill text to 68 colums
fill76 - refill text to 76 colums
tabindent - prefix every not empty line with tab
shortdate - iso 8631 date, no time zone
stringify - turn template iterator into string
if set, override default hgrc search path.
if empty, only .hg/hgrc of current repo read.
for each element, if directory, all entries in directory with end in
".rc" are added to path. else, element is added to path.
big thing about this change is that user "~/.hgrc" and system hgrc not
longer breaks tests. run-tests makes HGRCPATH empty now.
old style: symlink to pid
new style: symlink to hostname:pid
if lock code finds new-style lock, it breaks lock if locking pid is on
same machine and pid is not alive.
otherwise, lock is left alone. this makes locking code safe with
old-style locks and with locks on other machines.
new code makes server part of mercurial more robust in case machine
crashes, power fails, or crazy user does kill -9.
now it searches <install dir>/etc/mercurial, /etc/mercurial, and user
hgrc.
this allows site-wide configuration to be shared over automounted nfs
partition, instead of chenging on every system. option of having local
configuration on every system remains.
old code for searching /etc/mercurial/hgrc.d never worked, this code
is tested and works.
We used to pass changelog dates around as a "unixtime timezone" string
containing a pair of encoded ints. Now, they get passed around as a
(unixtime, timezone) tuple of numbers, which makes much more sense.
- moved popen("patch ...") from commands.py to util.py
- files may not be single quoted in popen under windows: fixed
- patch returns the files quoted under windows. quotes need to
be stripped off: fixed
Here is the new syntax, in summary.
Trailing white space is dropped.
The escape character is "\".
Comments start with #.
Empty lines are skipped.
Lines can be of the following formats:
syntax: regexp # defaults following lines to non-rooted regexps
syntax: glob # defaults following lines to non-rooted globs
re:pattern # non-rooted regular expression
glob:pattern # non-rooted glob
pattern # pattern of the current default type
The default pattern type is regexp, which is completely backwards
compatible with the old hgignore syntax.
In the dirstate class, the ignore method has been reworked to be based
on the util.matcher function, by way of a new dirstate.hgignore
method.
In order to use hardlinks, the win32file module is needed, and this is
present in ActivePython. If it isn't present, or hardlinks are not supported
on the underlying filesystem, a regular copy is used.
When using hardlinks the biggest benefit is probably the saving in space,
but cloning can be much quicker. For example cloning the Xen tree
(non trivial) without an update goes from about 95s to 15s.
Unix-like platforms should be unaffected, although should be more tolerant on
filesystems that don't support hard links.
(tweaked by mpm to deal with new copyfiles function)
--- hg.orig/mercurial/commands.py 2005-09-13 19:32:53.000000000 -0500
+++ hg/mercurial/commands.py 2005-09-14 12:11:34.000000000 -0500
@@ -620,10 +620,6 @@ def clone(ui, source, dest=None, **opts)
if other.dev() != -1:
abspath = os.path.abspath(source)
- copyfile = (os.stat(dest).st_dev == other.dev()
- and getattr(os, 'link', None) or shutil.copy2)
- if copyfile is not shutil.copy2:
- ui.note("cloning by hardlink\n")
# we use a lock here because if we race with commit, we can
# end up with extra data in the cloned revlogs that's not
@@ -638,7 +634,7 @@ def clone(ui, source, dest=None, **opts)
for f in files.split():
src = os.path.join(source, ".hg", f)
dst = os.path.join(dest, ".hg", f)
- util.copyfiles(src, dst, copyfile)
+ util.copyfiles(src, dst)
repo = hg.repository(ui, dest)
Index: hg/mercurial/util.py
===================================================================
--- hg.orig/mercurial/util.py 2005-09-08 00:15:25.000000000 -0500
+++ hg/mercurial/util.py 2005-09-14 12:16:49.000000000 -0500
@@ -12,7 +12,7 @@ platform-specific details from the core.
import os, errno
from demandload import *
-demandload(globals(), "re cStringIO")
+demandload(globals(), "re cStringIO shutil")
def binary(s):
"""return true if a string is binary data using diff's heuristic"""
@@ -217,17 +217,28 @@ def rename(src, dst):
os.unlink(dst)
os.rename(src, dst)
-def copyfiles(src, dst, copyfile):
- """Copy a directory tree, files are copied using 'copyfile'."""
+def copyfiles(src, dst, hardlink=None):
+ """Copy a directory tree using hardlinks if possible"""
+
+ if hardlink is None:
+ hardlink = (os.stat(src).st_dev ==
+ os.stat(os.path.dirname(dst)).st_dev)
if os.path.isdir(src):
os.mkdir(dst)
for name in os.listdir(src):
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
- copyfiles(srcname, dstname, copyfile)
+ copyfiles(srcname, dstname, hardlink)
else:
- copyfile(src, dst)
+ if hardlink:
+ try:
+ os_link(src, dst)
+ except:
+ hardlink = False
+ shutil.copy2(src, dst)
+ else:
+ shutil.copy2(src, dst)
def opener(base):
"""
@@ -244,13 +255,13 @@ def opener(base):
if mode[0] != "r":
try:
- s = os.stat(f)
+ nlink = nlinks(f)
except OSError:
d = os.path.dirname(f)
if not os.path.isdir(d):
os.makedirs(d)
else:
- if s.st_nlink > 1:
+ if nlink > 1:
file(f + ".tmp", "wb").write(file(f, "rb").read())
rename(f+".tmp", f)
@@ -266,10 +277,41 @@ def _makelock_file(info, pathname):
def _readlock_file(pathname):
return file(pathname).read()
+def nlinks(pathname):
+ """Return number of hardlinks for the given file."""
+ return os.stat(pathname).st_nlink
+
+if hasattr(os, 'link'):
+ os_link = os.link
+else:
+ def os_link(src, dst):
+ raise OSError(0, "Hardlinks not supported")
+
# Platform specific variants
if os.name == 'nt':
nulldev = 'NUL:'
+ try: # ActivePython can create hard links using win32file module
+ import win32file
+
+ def os_link(src, dst): # NB will only succeed on NTFS
+ win32file.CreateHardLink(dst, src)
+
+ def nlinks(pathname):
+ """Return number of hardlinks for the given file."""
+ try:
+ fh = win32file.CreateFile(pathname,
+ win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
+ None, win32file.OPEN_EXISTING, 0, None)
+ res = win32file.GetFileInformationByHandle(fh)
+ fh.Close()
+ return res[7]
+ except:
+ return os.stat(pathname).st_nlink
+
+ except ImportError:
+ pass
+
def is_exec(f, last):
return last
iterator over strings (aka chunks).
Also added to util (for future use) is a generator function that
iterates over a file n bytes at a time.
Lastly, localrepo was changed to use this new chunkbuffer class when
reading changegroups form the local repository.
- create new statichttprepo class
- pull remote bits out of localrepo
- pull remote bits out of util.opener
- switch hg.repository to use statichttprepo
The original implementation of log walked backwards through history,
which had terrible behaviour. It took several minutes to view
complete kernel change history on a fast machine, for example.
The rewrite uses a windowed approach to walk hunks of history
forwards, while still giving results in reverse order. This reduces
run time from five minutes to five seconds on my system.
In addition, the rewrite uses our normal name handling mechanisms, so
you can run a command like "hg log net/ipv4/**.c" and get a useful
answer. It optimises for three different cases (no arguments, only
files, and anything goes), so it performs well in all circumstances
I've tested.
Based on a patch by Fuming Wang
- add util.binary which decides whether a file is binary if it has any NUL
characters in the first 1K.
- teach mdiff.unidiff to print "binary file <x> has changed" for binary files
- add text flag to cause unidiff and dodiff to treat all files as text
- add -a and --text flags (like diff(1)) to hg diff and export
- update docs
Most read operations in hg don't need locks because we order reads and
writes for consistency. Clone is an exception to this as we're copying
entire file histories and could end up with more file history copied
than we have commits.
For now, make clone take a lock on the source repo. Non-hardlinked
clone should eventually be changed to use lockless pull.
Prior to this, a file that did not exist was reported as showing up in
the filesystem, as were files of unsupported types (such as fifos).
Now, an error message is printed and nothing is returned in such cases.
This change also moves the commands.pathto function to the util module,
as the walk code needs it to print non-confusing error messages.
The first consequence of this is that absolute and relative paths now
all work in the same way. The second is that paths that lie outside
the repository now cause an error to be reported, instead of something
arbitrary and expensive being done.
Internally, all of the serious work is in the util package. The new
canonpath function takes an arbitrary path and either returns a
canonical path or raises an error. Because it needs to know where the
repository root is, it must be fed a repository or dirstate object, which
has given commands.matchpats and friends a new parameter to pass along.
The util.matcher function uses this to canonicalise globs and relative
path names.
Meanwhile, I've moved the Abort exception from commands to util, and
killed off the redundant util.CommandError exception.
New function: commands.pathto returns the relative path from one path
to another. For example, given foo/bar and baz/quux, it will return
../../baz/quux. This new function is used by the walk and status code
to print relative paths correctly.
New command: debugwalk exercises the walk code without doing anything
more.
hg.dirstate.walk now yields normalised names. For example, if you're
in the baz directory and you ask it to walk ../foo/bar/.., it will yield
names starting with foo/.
As a result of this change, all of the other walk and changes methods
in this module also return normalised names.
The util.matcher function now normalises globs and path names, so that
it will match normalised names properly.
Finally, util.matcher uses the non-glob prefix of a glob to tell walk
which directories to scan. Perviously, a glob like foo/* would scan
everything, but only return matches for foo/*. Now, foo/* only scans
under foo (using the globprefix function), which is much faster.
When we switched to the new walk code for commands, we no longer passed a
list of specific files to the repo or dirstate walk or changes methods.
This meant that we always walked and attempted to match everything,
which was not efficient.
Now, if we are given any patterns to match, or nothing at all, we still
walk everything. But if we are given only file names that contain no
glob characters, we only walk those.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Make makelock and readlock work on filesystems without symlink support.
This way you can have a repository on a fat partiton, e.g. a USB stick.
manifest hash: cea2c120ef2b25a50c5d98b59648f773feefe470
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
iD8DBQFC1t5yW7P1GVgWeRoRAsKjAJ9BFcn/EqBK/dmJ4BY1pPIZIbDDJACghN3p
VCQS6CJ72MHpzhOOsnOpHzE=
=laDT
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Use python function instead of external 'cp' command when cloning repos.
Inspired by a patch from Stephen Darnell.
manifest hash: b525b0bf40f349b362db7c46d62be41572ef65cf
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
iD8DBQFC1ncZW7P1GVgWeRoRAiJmAJ9GaCPaG6yOKb72I+SpDDdcdXTISACePD0H
GR/F+qqzi2imdgIV77ziLcQ=
=YVd2
-----END PGP SIGNATURE-----
# HG changeset patch
# User mark.williamson@cl.cam.ac.uk
# Node ID 55d38977b7f2e73b8c1090179928ac96c8922b90
# Parent 0bda45294416406d4c6fbaf1cb643dd0bf6b3a16
A number of minor fixes to problems that pychecker found.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[PATCH] Harden os.system
From: Bryan O'Sullivan <bos@serpentine.com>
Add util.system function. This is similar to os.system, but will
either succeed (if the process finishes with a zero exit code) or raise
a util.CommandError (if the process exits uncleanly or is killed by
a signal).
Add util.explain_exit function. This tends to be ubiquitous in code
that calls other processes, and must describe what has gone wrong.
Change some uses of os.system over to util.system.
manifest hash: e3bf4adcac5b915432ec0af00efdbcef86bea4b1
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCwSipywK+sNU5EO8RAr0RAJkBDt8XQ7mYQAWNHNgTOVt1eyWU1QCfe1oO
2OwxyWqpbRNACVJHHfZ3/Xw=
=OaRX
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[PATCH] /dev/null for other OS
From: K Thananchayan <thananck@yahoo.com>
Null device name is platform dependent. Introduce util.nulldev
- - platform dependent constant and use it instead of '/dev/null'
manifest hash: 95a1bfdb712c53ef97aaff73f7f4c87e9299cf59
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCvQCGywK+sNU5EO8RAiRBAKCcXasCCFT2+6wgklkgqIt4l3UwugCeKWii
h/8iRYEw8Rp8B67abiFiwyY=
=L3Mk
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Permission handling for the other OS
From: K Thananchayan <thananck@yahoo.com>
Preserve exec permission under Windows on existing source files. Not an ideal
solution as there is no way to specify exec permission for a new file.
Nevertheless, this helps working on crossplatform projects.
manifest hash: c50da52ad4645f40bd6204c4fd458e880bc3f801
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCuvJeywK+sNU5EO8RAscXAJ40eAHZjTip5to6BGPdoXxxL5gNQQCgl5GT
8S1Ckank5I/0ScGtapZKqTA=
=QrQp
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[PATCH] Enables lock work under the other 'OS'
From: K Thananchayan <thananck@yahoo.com>
os.symlink is not supported under Windows. This patch
introduces util.mklockf, util.getlowner that use
regular files under Winodws but symlink under unix.
tweaked by mpm:
- changed function names
- fixed to work on UNIX
manifest hash: 6f650a78a3b203dcad2f861582500b6b4036599a
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCuN5sywK+sNU5EO8RAva8AJ9L9z/JHRAJS1bix48ZzSpn9ZUyPwCffhmg
UfLSFBmd5tPDDi3mgsrdDEA=
=ZYS9
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[PATCH] rename under the other OS
From: K Thananchayan <thananck@yahoo.com>
Rename fails under windows if dest file exists. This
patch add a rename method to util module that removes
the dest file and retries if initial attempt fails.
manifest hash: 2744d9fd1717e15133b411a269df909fa8ec0faf
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCuNzDywK+sNU5EO8RAsPBAJ9NQN3bTuJvTem5x+utGnoMkhYc0QCbBFSJ
PoMP69H1UnVE6drFlnlFE0s=
=pePw
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[PATCH] file seperator handling for the other 'OS'
From: K Thananchayan <thananck@yahoo.com>
The following patch maintains repo root relative source file names in
canonical form (with '/' as file seperator).
Mercurial calls os.path.join, os.path.normpath, os.path.walk that use
platform's file seperator. This patch does not change seperator in
these circumstances (except when the result refer to source files).
manifest hash: 2fbb4cb0d3d0bc4f4de5c7c8803fb738072ec6c5
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCuNuBywK+sNU5EO8RAhAZAKCV8cz11+rdof9n1tHb0uDScF34GgCeITNi
4aVikToPXqXyReN9kFP5pnY=
=xcV5
-----END PGP SIGNATURE-----