Add missing calls to close() to many places where files are
opened. Relying on reference counting to catch them soon-ish is not
portable and fails in environments with a proper GC, such as PyPy.
Defers updating the fncache file with newly added entries to the end of
the transaction (on e.g. pull), doing a single open call on the fncache
file, instead of opening and closing it each time a new entry is added
to the store.
Implemented by adding a new abstract write() function on store.basicstore
and registering it as a release function on the store lock in
localrepo.lock (compare with dirstate.write).
store.fncachestore overrides write() from basicstore and calls a new
write function on the fncache object, which writes all entries to the
fncache file if it's dirty.
store.fncache.add() now just marks itself as dirty if a new name is added.
Some extensions (e.g. hgsubversion) completely override push command. Because
extensions load order is unspecified, if hgsubversion loads before mq, mq
checks about not pushing applied patches will be bypassed. Short of finding a
way to fix load order, extracting the checking logic will allow
hgsubversion-like extensions to run the check themselves.
The generation of cache files like tags.cache and branchheads.cache is not an
actual reflection of things changing in the whole of the .hg directory (like eg
a commit or a rebase or something) but instead these cache files are just part
of bookkeeping. As such its convienant to allow various clients to ignore file
events to do with these cache files which would otherwise cause a double
refresh. Eg one refresh might occur after a commit, but the act of refreshing
after the commit would cause Mercurial to generate a new branchheads.cache which
would then cause a second refresh, for clients.
However if these cache files are moved into a directory like eg .hg/cache/ then
GUI clients on OSX (and possibly other platforms) can happily ignore file events
in this cache directory.
These leaks may occur in environments that don't employ a reference
counting GC, i.e. PyPy.
This implies:
- changing opener(...).read() calls to opener.read(...)
- changing opener(...).write() calls to opener.write(...)
- changing open(...).read(...) to util.readfile(...)
- changing open(...).write(...) to util.writefile(...)
This speeds up the in-memory version of debugbuilddag that I'm
working on considerably for the case where we want to build just
a 00changelog.i (for discovery tests, for instance).
There are a couple of test changes because node ids in tests
have changed.
The changes to the patch names in test-mq-qdelete.t were required
because they could collide with nodeid abbreviations and newly
actually do (patch "c" collides with id "cafe..." for patch "b").
All tests repeatedly passes with a3900c75ca8c on some machines, but on other
machines it regularly causes failure in test-mv-cp-st-diff.t, such as:
@@ -203,6 +203,7 @@
- working to root: --rev 0
M a
+ M x/x
A b
a
The introduction of the new URL parsing code has created a startup
time regression. This is mainly due to the use of url.hasscheme() in
the ui class. It ends up importing many libraries that the url module
requires.
This fix helps marginally, but if we can get rid of the urllib import
in the URL parser all together, startup time will go back to normal.
perfstartup time before the URL refactoring (707e4b1e8064):
! wall 0.050692 comb 0.000000 user 0.000000 sys 0.000000 (best of 100)
current startup time (9ad1dce9e7f4):
! wall 0.070685 comb 0.000000 user 0.000000 sys 0.000000 (best of 100)
after this change:
! wall 0.064667 comb 0.000000 user 0.000000 sys 0.000000 (best of 100)
This is a long desired cleanup and paves the way for new discovery.
To specify subsets for bundling changes, all code should use the heads
of the desired subset ("heads") and the heads of the common subset
("common") to be excluded from the bundled set. These can be used
revlog.findmissing instead of revlog.nodesbetween.
This fixes an actual bug exposed by the change in test-bundle-r.t
where we try to bundle a changeset while specifying that said changeset
is to be assumed already present in the target. This used to still
bundle the changeset. It no longer does. This is similar to the bugs
fixed by the recent switch to heads/common for incoming/pull.
Updating the branch cache is quadratic to the amount of heads in the
repository. One consequence of this was that cloning a pathological
repository with 10,000 heads (and nothing else) took hours of CPU
time.
This patch makes one of the inner loop much faster, by removing a
changectx instantiation, and removes another entirely in cases where
there are no candidate branch heads which descend from other branch
heads.
New argument is silently ignored by both HTTP and SSH servers.
This means we can, for instance, add new flags to getbundle()
to request advanced features (like lightweight-copy-aware bundles),
and older servers will silently ignore this request and send back
a plain bundle.
If a closed head gets pulled, we currently see (example):
$ hg pull
pulling from $TESTTMP/repo2
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
A subsequent 'hg heads' doesn't show that head because it is closed.
This patch improves the UI response texts for that same use case to:
$ hg pull
pulling from $TESTTMP/repo2
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)
That is, the part "(+1 heads)" is not shown in that case any longer.
If a file is deleted (rm, not 'hg rm') from the working dir
an attempt to run 'hg diff -r X', with the file being present in X will
cause an abort.
We didn't check if the file has been deleted from the working dir
and later on tried to open it to compare with the one from X, causing the abort.
This fix adds that check. Consequently, no output will be returned.
The manifest value of a file will never be false when "not parentworking", and
the expensive content comparision would thus fortunately never be reached. (If
it was reached it would be wrong for example in case of renames.)
This code once handled status against working directory, but that has been done
elsewhere for a long time.
This replaces util.drop_scheme() with url.localpath(), using url.url for
parsing instead of doing it on its own. The function is moved from
util to url to avoid an import cycle.
hg.localpath() is removed in favor of using url.localpath(). This
provides more consistent behavior between "hg clone" and other
commands.
To preserve backwards compatibility, URLs like bundle://../foo still
refer to ../foo, not /foo.
If a URL contains a scheme, percent-encoded entities are decoded. When
there's no scheme, all characters are left untouched.
Comparison of old and new behaviors:
URL drop_scheme() hg.localpath() url.localpath()
=== ============= ============== ===============
file://foo/foo /foo foo/foo /foo
file://localhost:80/foo /foo localhost:80/foo /foo
file://localhost:/foo /foo localhost:/foo /foo
file://localhost/foo /foo /foo /foo
file:///foo /foo /foo /foo
file://foo (empty string) foo /
file:/foo /foo /foo /foo
file:foo foo foo foo
file:foo%23bar foo%23bar foo%23bar foo#bar
foo%23bar foo%23bar foo%23bar foo%23bar
/foo /foo /foo /foo
Windows-related paths on Windows:
URL drop_scheme() hg.localpath() url.localpath()
=== ============= ============== ===============
file:///C:/foo C:/C:/foo /C:/foo C:/foo
file:///D:/foo C:/D:/foo /D:/foo D:/foo
file://C:/foo C:/foo C:/foo C:/foo
file://D:/foo C:/foo D:/foo D:/foo
file:////foo/bar //foo/bar //foo/bar //foo/bar
//foo/bar //foo/bar //foo/bar //foo/bar
\\foo\bar //foo/bar //foo/bar \\foo\bar
Windows-related paths on other platforms:
file:///C:/foo C:/C:/foo /C:/foo C:/foo
file:///D:/foo C:/D:/foo /D:/foo D:/foo
file://C:/foo C:/foo C:/foo C:/foo
file://D:/foo C:/foo D:/foo D:/foo
file:////foo/bar //foo/bar //foo/bar //foo/bar
//foo/bar //foo/bar //foo/bar //foo/bar
\\foo\bar //foo/bar //foo/bar \\foo\bar
For more information about file:// URL handling, see:
http://www-archive.mozilla.org/quality/networking/testing/filetests.html
Related issues:
- issue1153: File URIs aren't handled correctly in windows
This patch should preserve the fix implemented in
5c92d05b064e. However, it goes a step further and "promotes"
Windows-style drive letters from being interpreted as host names to
being part of the path.
- issue2154: Cannot escape '#' in Mercurial URLs (#1172 in THG)
The fragment is still interpreted as a revision or a branch, even in
paths to bundles. However, when file: is used, percent-encoded
entities are decoded, so file:test%23bundle.hg can refer to
test#bundle.hg ond isk.
split can be more readable for longer lists like the list in
dirstate.invalidate. As dirstate.invalidate is used in wlock() and therefoe
used heavily, I think it's worth avoiding a split there too.
This patch avoids empty commit when .hgsubstate is dirty. Empty commit
was caused by .hgsubstate being updated back to the state of the
working copy parent when committing, if a user had changed it manually
and not made any changes in subrepositories.
The subrepository state from the working copies parent is compared
with the state calculated as a result of trying to commit the
subrepositories. If the two states are the same, then return None
otherwise the commit is just done.
The line: "committing subrepository x" will be written if there is
nothing committed, but .hgsubstate is dirty for x subrepository.
This uses the same strategy as progress for pulls, estimating manifests
based on changeset count and estimating file count by files list in
each changeset.
The opener already unlinks the filename before 'w'riting, for both
the symlink and the normal file case. It also now resets the flags
for normal files on 'w'rite, which makes this os.unlink call completely
redundant.
For Windows, removing this extra unlink call helps to avoid tripping
issue2524 (os.unlink followed by a write).
Previously, branch names were ideally manipulated as UTF-8 strings,
because they were stored as UTF-8 in the dirstate and the changelog
and could not be safely converted to the local encoding and back.
However, only about 80% of branch name code was actually using the
right encoding conventions. This patch uses the localstr addition to
allow working on branch names as local strings, which simplifies
handling so that the previously incorrect code becomes correct.
When issuing `hg pull -r REV` in a repo with no common ancestor with the
remote repo, the message 'requesting all changes' is printed, even though only
the changese that are ancestors of REV are actually requested. This can be
confusing for users (see
http://www.selenic.com/pipermail/mercurial/2010-October/035508.html).
This silences the message if (and only if) the '-r' option was passed.
- Mac OS X has problems with filenames starting with '._'
(e.g. '.FOO' -> '._f_o_o' is now encoded as '~2e_f_o_o')
- Explorer of Windows Vista and Windows 7 strip leading spaces of
path elements of filenames when copying trees
Above problems are avoided by encoding the first space (as '~20') or
period (as '~2e') of all path elements.
This introduces a new entry 'dotencode' in .hg/requires, that is,
a new repository filename layout (inside .hg/store).
Newly created repositories require 'dotencode' by default. Specifying
[format]
dotencode = False
in a config file will use the old format instead.
Prior Mercurial versions will abort with the message
abort: requirement 'dotencode' not supported!
when trying to access a local repository that requires 'dotencode'.
New 'dotencode' repositories can be converted to the previous
repository format with
hg --config format.dotencode=0 clone --pull repoA repoB
This patch fixes issues with stream cloning in the presense of parentdelta,
lwcopy and similar additions that change the interpretation of the revlog
format, or the format itself.
Currently, the stream capability is sent like this:
stream=<version of changelog>
But the client doesn't actually check the version number; also, it only checks
the changelog and it doesn't capture the interpretation-changes and
flag-changes in parentdelta and lwcopy.
This patch removes the 'stream' capability whenever we use a non-basic revlog
format, to prevent old clients from receiving incorrect data. In those cases,
a new capability called 'streamreqs' is added instead. Instead of a revlog
version, it comes with a list of revlog-format relevant requirements, which
are a subset of the repository requirements, excluding things that are not
relevant for stream.
New clients use this to determine whether or not they can stream. Old clients
only look for the 'stream' capability, as always. New servers will still send
this when serving old repositories.
Currently, localrepo.branchtags() is called in two locations to update the
_branchcache dict, however branchtags() itself does not update anything, it
calls branchmap() to do so. This change introduces a new updatebranchcache()
method that is used by both branchmap() and the calls to update the cache.
This method was introduced by b0e5c3bce42a but grepping the history does not
reveal any call. Extensions may use it but the method intent is not even clear
to me.
Separate loading part from access part to be able to tell with:
repo._loadfilter(name)
bool(name in repo.filterpats)
if there is a 'name' filter available.