spawndetached() was the only user of _STARTF_USESHOWWINDOW and it creates the
process with _CREATE_NO_WINDOW anyway. If the process has no window, then
there is nothing to hide.
Before this change, a console window briefly popped up on "hg serve -d" and
disappeared again, stealing the focus window (which was very annyoing when
running tests).
Specifying _CREATE_NO_WINDOW instead of _DETACHED_PROCESS fixes this (as tested
on Windows 7 x64).
The problem occured when pushing a changeset that at the same time creates a
new named branch head and moves a bookmark. The code invoked methods that only
exist on localrepo instances, so it failed for any other type of remote. The
test suite only tested against local remotes.
When requesting files using statichttprepo.httprangereader, a request for the
entire file is sent with a Range: bytes=0- header. This causes problems with
web servers such as Cherokee that return an HTTP 416 when an empty file is
requested in this way, which in turn cause some repository clone attempts to
fail. This patch omits the Range header when the entire file is being
requested, which fixes the problem.
When applying a patch renaming/copying 'a' to 'b' on a revision where
'a' does not exist, the patching process would abort immediately,
without processing the remaining hunks and without reporting it. This
patch makes the patching no longer abort and possible hunks applied on
the copied/renamed file be written in reject files.
b67b333b0d8a attempted to force the filecaches in localrepo to reload
everything after a rollback. But simply clearing _filecache isn't enough,
invalidate() needs to be called before/after. localrepo._rollback calls
invalidate() already, so we clear the map right afterwards which ensures
everything will be reread.
This is about 9 times faster than the Python dirstate packing code.
The relatively small speedup is due to the poor locality and memory
access patterns caused by traversing dicts and other boxed Python
values.
There are two sets of Python re2 bindings available on the internet;
this code works with both.
Using re2 can greatly improve "hg status" performance when a .hgignore
file becomes even modestly complex.
Example: "hg status" on a clean tree with 134K files, where "hg
debugignore" reports a regexp 4256 bytes in size.
no .hgignore: 1.76 sec
Python re: 2.79
re2: 1.82
The overhead of regexp matching drops from 1.03 seconds with stock
re to 0.06 with re2.
(For comparison, a git repo with the same contents and .gitignore
file runs "git status -s" in 1.71 seconds, i.e. only slightly faster
than hg with re2.)
This patch fixes the synopsis shown for extension commands in keyword search
results. A previous patch erroneously caused the extension synopsis to be shown
instead.
Test cases for keyword search are missing, so I added a one.
This patch fixes the broken formatting of keyword search results. Some blank
lines were missing from the RST markup, which caused markup to be printed.
This will be used as a step in removing reachable() in a future diff.
Doing it now because bryano is in the process of rewriting ancestors in
C. This depends on bryano's patch to replace *revs with revs in the
declaration of revlog.ancestors.
Accepting a variable number of arguments as the old API did is
deeply ugly, particularly as it means the API can't be extended
with new arguments. Partly as a result, we have at least three
different implementations of the same ancestors algorithm (!?).
Most callers were forced to call ancestors(*somelist), adding to
both inefficiency and ugliness.
The config.sortdict class is a simple "sorted dictionary" container
class, based on python's regular dict container. The main difference
compared to regular dicts is that sortdicts remember the order in
which items have been added to it.
Without this patch the items() method returns the sortdict elements in
the right order. However, getting the list of keys by using the keys()
or iterkeys() methods, and consequencly, looping through the container
elements in a for loop does not respect that order. This patch fixes
this problem.
This patch changes the function which generates help text about commands and
options to use RST formatting. Tables describing options have been formatted
using RST table markup for some time already, so their appearance does not
change. Command lists, however, change appearance.
To format non-verbose command lists, RST field list markup was chosen, because
it resembles the old format:
<http://docutils.sourceforge.net/docs/user/rst/quickref.html#field-lists>
In the old (hand-coded) format of non-verbose command lists, the left column is
12 characters wide. Our minirst implementation formats field lists with a left
column 14 characters wide, so this patch changes the appearance of help output
correspondingly:
<http://markmail.org/message/krl4cxopsnii7s6z?q=mercurial+reinert+from:%22Olav+Reinert%22&page=2>
The minirst markup most closely resembling the old verbose command lists is
definition lists. But using it would cause a blank line to be inserted between
each command definition, making the output excessively long, and no more
useful than before. To avoid this, I chose to use field lists also for verbose
command help, resulting in output like this example:
add add the specified files on the next commit
annotate, blame
show changeset information by line for each file
clone make a copy of an existing repository
commit, ci commit the specified files or all outstanding changes
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
init create a new repository in the given directory
log, history show revision history of entire repository or files
merge merge working directory with another revision
phase set or show the current phase name
pull pull changes from the specified source
push push changes to the specified destination
qdiff diff of the current patch and subsequent modifications
qinit init a new queue repository (DEPRECATED)
qnew create a new patch
qpop pop the current patch off the stack
qpush push the next patch onto the stack
qrefresh update the current patch
remove, rm remove the specified files on the next commit
serve start stand-alone webserver
status, st show changed files in the working directory
summary, sum summarize working directory state
update, up, checkout, co
update working directory (or switch revisions)
This change is a move towards generating all help text as a list of strings
marked up with RST.
Keyword search in help (introduced in d455a324f54f and ff267c569bea by Augie
Fackler) tries to translate already translated strings, which results in
Unicode errors in gettext when non-ASCII locale is used. Also command
descriptions should be translated before searching there (thanks to FUJIWARA
Katsunori for pointing this out and actual fix), (issue3482).
When developing, we may see non-standard version strings of the form
5d64306f39bb+20120525
which caused tuplever() to raise
ValueError: invalid literal for int() with base 10: '5d64306f39bb'
and shadowing the real traceback.
Caching has no performance effect on the revset aliases which triggered
the recent recursive evaluation bug. I wrote it not to feel bad about
expanding several times the same complicated expression.
'exact' match objects are sometimes created with a non-list 'pattern'
argument:
- using 'set' in queue.refresh():hgext/mq.py
match = scmutil.matchfiles(repo, set(c[0] + c[1] + c[2] + inclsubs))
- using 'dict' in revert():mercurial/cmdutil.py (names = {})
m = scmutil.matchfiles(repo, names)
'exact' match objects return specified 'pattern' to callers of
'match.files()' as it is, so it is a non-list object.
but almost all implementations expect 'match.files()' to return a list
object, so this may causes problems: e.g. exception for "+" with
another list object.
this patch ensures that '_files' of 'exact' match objects is a list
object.
for non 'exact' match objects, parsing specified 'pattern' already
ensures that it it a list one.
The alias expansion code it changed from:
1- Get replacement tree
2- Substitute arguments in the replacement tree
3- Expand the replacement tree again
into:
1- Get the replacement tree
2- Expand the replacement tree
3- Expand the arguments
4- Substitute the expanded arguments in the replacement tree
and fixes cases like:
[revsetalias]
level1($1, $2) = $1 or $2
level2($1, $2) = level1($2, $1)
$ hg log -r "level2(level1(1, 2), 3)"
where the original version incorrectly aborted on infinite expansion
error, because it was confusing the expanded aliases with their
arguments.
The current revset alias expansion code works like:
1- Get the replacement tree
2- Substitute the variables in the replacement tree
3- Expand the replacement tree
It makes it easy to substitute alias arguments because the placeholders
are always replaced before the updated replacement tree is expanded
again. Unfortunately, to fix other alias expansion issues, we need to
reorder the sequence and delay the argument substitution. To solve this,
a new "virtual" construct called _aliasarg() is introduced and injected
when parsing the aliases definitions. Only _aliasarg() will be
substituted in the argument expansion phase instead of all regular
matching string. We also check user inputs do not contain unexpected
_aliasarg() instances to avoid argument injections.
This function augments strip to incrementally update the branchheads cache
rather than recompute it from scratch. This speeds up the performance of strip
and rebase on repos with long history. The performance optimization only
happens if the revisions stripped are all on the same branch and the parents of
the stripped revisions are also on that same branch.
This adds a few test cases, particularly one that reproduces the extra heads
that mpm observed.
_updatebranchcache used to use revlog.reachable. After the switch to
revlog.ancestors, we can now clean it up a bit and switch the algorithm from
nodes to revs.
ancestors() returns the ancestors of revs provided. This func is like
that except it also includes the revs themselves in the total set of
revs generated.
Fixes (on Windows in cmd.exe):
$ hg -R v:\x\a status V:\x\a\bar
abort: V:\x\a\bar not under root
where v:\x\a is a valid repository with a checked-out file "bar"
(Note the difference in casing: "v:\" versus "V:\")
graft, transplant and rebase all embed a different type of source marker in
extra, and each with a different name. The current implementation of each is
such that there will never be more than one of these markers on a node.
Note that the rebase marker can only be resolved if the source is
still present, which excludes the typical rebase usage (without
--keep) from consideration (unless the resulting bundle in
strip-backup is overlayed). There probably isn't any reason to use
rebase --keep as a substitute for transplant or graft at this point,
but maybe there was at one point and there are even a few rebases in
the hg repo, so it may be of historical interest.
If the string provided to the 'tag' predicate starts with 're:', the rest
of the string will be treated as a regular expression and matched against
all tags in the repository.
There is a slight backwards-compatibility problem for people who actually
have tags that start with 're:'. As a workaround, these tags can be matched
using a 'literal:' prefix.
If no tags match the pattern, an error is raised. This matches the behaviour
of the previous exact-match code.
This is a partial backout of 7efea3b5db4c.
7efea3b5db4c switched win32.py to using ctypes with the intention to get rid
of the dependency on the pywin32 package.
But 7efea3b5db4c replaced the usage of the Python standard module _winreg in
lookup_reg as well, which was uneeded (note that lookup_reg was later renamed
into lookupreg).
Basically, we're switching back to the previous _winreg-based implementation,
which uses _winreg.QueryValueEx(). QueryValueEx returns a unicode code string.
See also: issue3467
There have been quite a few places where we pop elements off the
front of a list. This can turn O(n) algorithms into something more
like O(n**2). Python has provided a deque type that can do this
efficiently since at least 2.4.
As an example of the difference a deque can make, it improves
perfancestors performance on a Linux repo from 0.50 seconds to 0.36.
For divergent renames the following message is printed during merge:
note: possible conflict - file was renamed multiple times to:
newfile
file2
When a file is renamed in one branch and deleted in the other, the file still
exists after a merge. With this change a similar message is printed for mv+rm:
note: possible conflict - file was deleted and renamed to:
newfile
Although index_headrevs is much faster than its Python counterpart,
it's still somewhat expensive when history is large. Since headrevs
is called several times when the tag cache is stale or missing (e.g.
after a strip or rebase), there's a win to be gained from caching
the result, which we do here.
The C implementation is more than 100 times faster than the Python
version (which is still available as a fallback).
In a repo with 330,000 revs and a stale .hg/cache/tags file, this
patch improves the performance of "hg tip" from 2.2 to 1.6 seconds.
This selects changesets added because of repo conversions. For example
hg log -r "converted()" # all csets created by a convertion
hg log -r "converted(rev)" # the cset converted from rev in the src repo
The converted(rev) form is analogous to remote(id), where the remote repo is
the source of the conversion. This can be useful for cross referencing an old
repository into the current one.
The source revision may be the short changeset hash or the full hash from the
source repository. The local identifier isn't useful. An interesting
ramification of this is if a short revision is specified, it may cause more
than one changeset to be selected. (e.g. converted(6) matches changesets with
a convert_revision field of 6e..e and 67..0)
The convert.hg.saverev option must have been specified when converting the hg
source repository for this to work. The other sources automatically embed the
converted marker.
This is achieved by acting as if the user had given -r<rev> for each head rev
of outgoing changesets on the command line, as well as appropriate
--base <rev>.
The discovery information is computed as normal, and then adjusted as above.
On an Irix 6.5.24 system, TIOCGWINSZ is not available. This means that
any usage of the "hg" tool that looks up the terminal size (e.g. "hg
help") will fail with an AttributeError.
A simple work-around is just to wrap this block in mercurial/posix.py
with a try/except so that it ends up using the default 80 characters
width.
Previously, we were finding the most recent version of a file in a
changeset and comparing it against its first file parent. This was
wrong on three counts:
- it would show a diff in revisions where there was no change to a file
- it would show a diff when only the exec bit changed
- it would potentially compare against a much older changeset, which
could be very expensive if git-style rename detection was enabled
This compares the file in the current context with that context's
parent, which may result in an empty diff when looking at a file not
touched by the current changeset.
Previously, graph data has been encoded for processing done by
JavaScript code run in the browser, employing simple structures
with implicit member positions. This patch modifies the graph
command to also produce data employing a dictionary-based
structure suitable for use with the templating mechanism, thus
permitting other ways of presenting repository graphs using that
mechanism.
In order to test these changes, the raw theme has been modified
to include templates for graph nodes and edges. In a similar
fashion, themes could employ technologies such as SVG that lend
themselves to templating to produce the graph display. This patch
makes use of a much simpler output representation than SVG in
order to maintain clarity.
The underlying C code doesn't support indexing by longs, there are no
legitimate reasons to use a long, and longs should generally be
converted to ints at a higher level by context's constructor.
Eliminates
mpatch.c(73) : warning C4244: 'return' : conversion from '__int64' to 'int',
possible loss of data
mpatch.c(299) : warning C4244: 'function' : conversion from 'Py_ssize_t' to
'int', possible loss of data
mpatch.c(321) : warning C4244: '=' : conversion from 'Py_ssize_t' to 'int',
possible loss of data
mpatch.c(335) : warning C4244: 'function' : conversion from 'Py_ssize_t' to
'int', possible loss of data
mpatch.c(346) : warning C4244: 'function' : conversion from 'Py_ssize_t' to
'int', possible loss of data
when compiling for Windows x64 target using the Microsoft compiler.
Until now, when calling subrepo.subrepo with a path at which there is no
subrepo, a "nullstate" tuple would be returned. However, this is not very
useful (the tuple can't really be used for creating a subrepo), so we'd just as
soon have the function just fail, and leave it up to the caller to decide what
to do.
The motivation for doing this now is to simplify the solution for (issue3056).
Eliminates
mercurial/bdiff.c(383) : warning C4244: 'function' : conversion from '__int64'
to 'uint32_t', possible loss of data
mercurial/bdiff.c(384) : warning C4244: 'function' : conversion from '__int64'
to 'uint32_t', possible loss of data
mercurial/bdiff.c(385) : warning C4244: 'function' : conversion from
'Py_ssize_t' to 'uint32_t', possible loss of data
when compiling for Windows x64 target using the Microsoft compiler.
Reduces the conversion warnings
mercurial/bdiff.c(61) : warning C4244: '=' : conversion from '__int64' to
'int', possible loss of data
mercurial/bdiff.c(307) : warning C4244: 'function' : conversion from
'Py_ssize_t' to 'int', possible loss of data
mercurial/bdiff.c(308) : warning C4244: 'function' : conversion from
'Py_ssize_t' to 'int', possible loss of data
mercurial/bdiff.c(362) : warning C4244: '+=' : conversion from '__int64' to
'int', possible loss of data
mercurial/bdiff.c(380) : warning C4244: '=' : conversion from '__int64' to
'int', possible loss of data
mercurial/bdiff.c(381) : warning C4244: 'function' : conversion from '__int64'
to 'uint32_t', possible loss of data
mercurial/bdiff.c(382) : warning C4244: 'function' : conversion from '__int64'
to 'uint32_t', possible loss of data
mercurial/bdiff.c(416) : warning C4244: '=' : conversion from 'Py_ssize_t' to
'int', possible loss of data
to
mercurial/bdiff.c(383) : warning C4244: 'function' : conversion from '__int64'
to 'uint32_t', possible loss of data
mercurial/bdiff.c(384) : warning C4244: 'function' : conversion from '__int64'
to 'uint32_t', possible loss of data
mercurial/bdiff.c(385) : warning C4244: 'function' : conversion from
'Py_ssize_t' to 'uint32_t', possible loss of data
on the three putbe32() calls in the function bdiff
when compiling for Windows x64 target using the Microsoft compiler.
Extension authors should explicitly declare their supported hg
versions and include a buglink attribute in their extension. In the
event that a traceback occurs, we'll identify the
least-recently-tested extensionas the most likely source of the defect
and suggest the user disable that extension.
Packagers should make every effort to ship hg versions from exact
tags, or with as few modifications as possible so that the versioning
can work appropriately.
Bookmarks will behave more like named branches when merge tries to pick
a revision to merge.
Bookmarks now to respect the current bookmarks. Bookmarks will not
accidentally merged with unnamed heads or other bookmarks. However merge
can pick heads with diverging bookmarks and pick those automatically.
We end up with two cases for picking a revision to merge:
(1) In case of an current bookmark, merge can pick a branch head that has a
diverged bookmark
(2) In case of no current bookmark, merge can pick a branch head that does not
have a bookmark.
Similar to branch heads we introduce the notion of bookmarkheads.
Bookmarkheads are changests that are bookmarked with the given bookmark
or a diverged version
Destroying history via strip used to invalidate the branchheads cache,
causing it to be regenerated the next time it is read. This is
expensive in large repos. This change converts strip to pass info to
localrepo.destroyed() to enable to it to incrementally update the
cache, improving the performance of strip and other operations that
depend on it (e.g., rebase).
This change also strengthens a bit the integrity checking of the
branchheads cache when it is read, by rejecting the cache if it has
nodes in it that no longer exist.
We allow rebase plus collapse, but not collapse only? I imagine people would
rebase first then collapse once they are sure the rebase is correct and it is
the right time to finish it.
I was reluctant to submit this patch for reasons detailed below, but it
improves rebase --collapse usefulness so much it is worth the ugliness.
The fix is ugly because we should be fixing the collapse code path rather than
the merge. Collapsing by merging changesets repeatedly is inefficient compared
to what commit --amend does: commitctx(), update, strip. The problem with the
latter is, to generate the synthetic changeset, copy records are gathered with
copies.pathcopies(). copies.pathcopies() is still implemented with merging in
mind and discards information like file replaced by the copy of another,
criss-cross copies and so forth. I believe this information should not be lost,
even if we decide not to interpret it fully later, at merge time.
The second issue with improving rebase --collapse is the option should not be
there to begin with. Rebasing and collapsing are orthogonal and a dedicated
command would probably enable a better, simpler ui. We should avoid advertizing
rebase --collapse, but with this fix it becomes the best shipped solution to
collapse changesets.
And for the record, available techniques are:
- revert + commit + strip: lose copies
- mq/qfold: repeated patching() (mostly correct, fragile)
- rebase: repeated merges (mostly correct, fragile)
- collapse: revert + tag rewriting wizardry, lose copies
- histedit: repeated patching() (mostly correct, fragile)
- amend: copies.pathcopies() + commitctx() + update + strip
Eliminates
mercurial/diffhelpers.c(143) : warning C4244: '=' : conversion from
'Py_ssize_t' to 'int', possible loss of data
mercurial/diffhelpers.c(144) : warning C4244: '=' : conversion from
'Py_ssize_t' to 'int', possible loss of data
when compiling for Windows x64 target using the Microsoft compiler.
Eliminates
mercurial/diffhelpers.c(81) : warning C4244: '=' : conversion from
'Py_ssize_t' to 'int', possible loss of data
mercurial/diffhelpers.c(82) : warning C4244: '=' : conversion from
'Py_ssize_t' to 'int', possible loss of data
when compiling for Windows x64 target using the Microsoft compiler.
Eliminates
mercurial/diffhelpers.c(23) : warning C4244: 'initializing' : conversion from
'Py_ssize_t' to 'int', possible loss of data
mercurial/diffhelpers.c(26) : warning C4244: 'initializing' : conversion from
'Py_ssize_t' to 'int', possible loss of data
mercurial/diffhelpers.c(27) : warning C4244: 'initializing' : conversion from
'Py_ssize_t' to 'int', possible loss of data
mercurial/diffhelpers.c(30) : warning C4244: 'initializing' : conversion from
'Py_ssize_t' to 'int', possible loss of data
when compiling for Windows x64 target using the Microsoft compiler.
The radix tree already contains all the information we need to
determine whether a short string is an unambiguous node identifier.
We now make use of this information.
In a kernel tree, this improves the performance of
"hg log -q -r24bf01de75" from 0.27 seconds to 0.06.
Since f7e538c3b7ba, if a chunk starts with "@@ -0,1", oldstart turns into
a negative value. Because diffhelpers.testhunk() doesn't expect negative bstart,
it bypasses "alen > blen - bstart" condition and segfaults at
"PyList_GET_ITEM(b, i + bstart)".
Before this, if advanceboundary() failed after updating some roots but
before calling retractboundary(), the phase cache would be left in an
invalid state, marked dirty, and written as such. This patch approach is
to turn advance/retractboundary() into phasecache methods, then operate
on copies and merge them back on success.
With the same technique, we can ensure the atomicity of combinations of
advance/retractboundary() calls, like those performed in changegroup
handling code.
The original motivation was changectx.phase() had special logic to
correctly lookup in repo._phaserev, including invalidating it when
necessary. And at other places, repo._phaserev was accessed directly.
This led to the discovery that phases state including _phaseroots,
_phaserev and _dirtyphase was manipulated in localrepository.py,
phases.py, repair.py, etc. phasecache helps encapsulating that.
This patch replaces all phase state in localrepo with phasecache and
adjust related code except for advance/retractboundary() in phases.
These still access to phasecache internals directly. This will be
addressed in a followup.
Commands working without a repository, like "init", are listed in
commands.norepo. Commands optionally using a repository, like "showconfig", are
listed in commands.optionalrepo. Command aliases were inheriting the former but
not the latter.
As detailed on http://docs.python.org/extending/newtypes.html (quote):
"In this case, we can just use the default implementation provided by the API
function PyType_GenericNew(). We’d like to just assign this to the
tp_new slot, but we can’t, for portability sake. On some platforms or
compilers, we can’t statically initialize a structure member with a function
defined in another C module, so, instead, we’ll assign the tp_new slot in the
module initialization function just before calling PyType_Ready()."
Fixes "gcc (GCC) 3.4.5 (mingw-vista special r3)" complaining with:
mercurial/parsers.c:1096: error: initializer element is not constant
mercurial/parsers.c:1096: error: (near initialization for `indexType.tp_new')
brendan mentioned on IRC that b64decode raises a TypeError too, but while the
previous exception type may be better in general, it is much easier to make it
behave like the related C code and changes nothing for mercurial itself.
When we encounter a corrupt index, we "fail" the init but our
destructor still gets called. On some systems, this was causing us to
attempt to decref a dangling to self->data.
Introduce manifestdict.withflags() to get a set of all files which have any
flags set, since these are likely to be a minority. Otherwise checking .flags()
for every file is a lot of dictionary lookups and is quite slow.
Introduce match.always() to check if a match object always says yes, i.e.
None was passed in. If so, mfmatches should not bother iterating every file in
the repository.
Eliminates
mercurial/parsers.c(515) : warning C4244: 'function' : conversion from
'Py_ssize_t' to 'long', possible loss of data
mercurial/parsers.c(520) : warning C4244: 'function' : conversion from
'Py_ssize_t' to 'long', possible loss of data
mercurial/parsers.c(521) : warning C4244: 'function' : conversion from
'Py_ssize_t' to 'long', possible loss of data
when compiling for Windows x64 target using the Microsoft compiler.
PyInt_FromSsize_t does not exist for Python 2.4 and earlier, so we define a
fallback in util.h to use PyInt_FromLong when compiling for Python 2.4.
Cosmetic cleanups. Fix comment typo referring to the notion of multiple tips.
Make variable describing a generator end in 'gen'.
Fix another var containing a node not to end with 'rev'.
Calling strip() will eventually trigger localrepo.destroyed() which will
invalidate _parseroots. It will call filterunknown() upon reload.
Changes to test-keyword.t are related to commit --debug running after
either qpop or rollback.
Since version 1.8 (released on 2011-03-01), Mercurial doesn't use pywin32 any
more. The old fallback mechanism to use C:\Mercurial\Mercurial.ini if pywin32 is
not installed was removed in 1fa0a833f143.
The line looks like "123 <node> <node>" and does not start with
whitespace: it was therefore not significant that rstrip was used
instead of strip. Furthermore, the first part is fed to int, which
will itself strip away whitespace before converting the string to an
integer.
Note that aborting in subrepo.state() prevents "repairing" commands like revert
to be issued. The user will have to edit the .hgsubstate manually (but he
probably had already otherwise this would not be failing). The same behaviour
already happens with invalid .hgsub entries.
This is most easily verified using valgrind on a long-running
process, as the leak has no visible consequences during normal
one-shot command usage.
In one window:
valgrind --leak-check=full --suppressions=valgrind-python.supp \
python ./hg serve
In another:
for ((i=0;i<100;i++)); do
curl -s http://localhost:8000/file/tip/README >/dev/null
done
valgrind should report no leaks.
The collapse configuration setting for hgweb was recently
introduced, but the help text was unfortunately omitted from the
patch concerned. This patch provides a suitable help text.
There is currently no clear link between the help for log
and the help on templates. The log option is --template
but the template help is 'help templating' or 'help templates'.
This patch makes 'hg help template' work and also adds a
note into the log help explaining where to find more info.
The initial version was to take the "Revision" field from svn info. It works
but produces false positive when parent paths are being moved or unrelated
changes are being committed, causing it to change while the svn checkout itself
remains the same. To avoid spurious commit, we took "Revision" and "Last
Changed Rev" for general comparison and kept the latter to answer "what is your
revision?" question. This is better but fails when the subrepo path exists at
"Revision" but not at "Last Changed Rev". This patch adds a check for this, and
returns "Revision" if the path does not exist. We try to avoid doing this as
much as possible at it implies an extra, *remote* call.
Messing with the dirstate before the intermediate commit seems error prone.
Instead, commit and recompute the copies with copies.pathcopies(), then use
that with commitctx().
Since copies.pathcopies() does not support file replacement very well, the
whole .renamed() condition in samefile() is removed and the "file replacement
caused by differing copy source" effect is discarded.
Test shamelessly stolen from Idan Kamara <idankk86@gmail.com>
The fix introduced in 3509b9cf8f86 was only partially successful. It is correct
to turn dirstate 'm' merge records into normal/dirty ones but copy records are
lost in the process. To adjust them as well, we need to look in the first
parent manifest to know which files were added and preserve only related
records. But the dirstate does not have access to changesets, the logic has to
moved at another level, in localrepo.
Brifly explain why rewriting subrepository paths can be necessary.
Explain that relative subrepository paths are made absolute before
rewrite rules are applied.
The original issue was something like:
$ hg init repo
$ cd repo
$ mkdir D
$ echo a > D/a
$ hg ci -Am adda
adding D/a
$ mv D temp
$ mv temp d
$ echo b > d/b
$ hg add d/b
adding D/b
$ hg ci -m addb
$ hg mv d/b d/c
moving D/b to d/c
$ hg st
A d/c
R D/b
Here we expected:
A D/c
R D/b
the logic being we try to preserve case of path components already known in the
dirstate. This is fixed by the current patch.
Note the following stories are not still not supported:
Changing directory case
$ hg mv D d
moving D/a to D/D/a
moving D/b to D/D/b
$ hg st
A D/D/a
A D/D/b
R D/a
R D/b
or:
$ hg mv D/* d
D/a: not overwriting - file exists
D/b: not overwriting - file exists
And if they were, there are probably similar issues with diffing/patching.
Here is a script illustrating the previous behaviour:
The merge brings a new file 'b' from remote
$ hg merge 1 --debug
searching for copies back to rev 1
unmatched files in other:
b
resolving manifests
overwrite: False, partial: False
ancestor: 07f494440405, local: 540395c44225+, remote: 102a90ea7b4a
b: remote created -> g
updating: b 1/1 files (100.00%)
getting b
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
Delete but do not remove b
$ rm b
$ hg st
! b
The commit succeeds
$ hg commit -m merge
$ hg parents --template "{rev} {desc|firstline} files: {files}\n"
3 merge files:
$ hg st
! b
b changes were ignored, but even b existence was ignored
$ hg manifest
a
This happens because localrepo.commitctx() checks the input ctx.files(), which
is empty for workingctx.files() only returns added, modified or removed
entries, and bypass files/manifest updates completely. So the committed
revision manifest is the same as its first parent one, not containing the 'b'
file.
This patch forces the commit to abort in presence of a merge and missing files.
test-merge4.t is modified accordingly as it was introduced to check hg was not
just terminating with a traceback (5cc0d3ba11f9).