Upon pull or unbundle, we display a message with the range of new revisions
fetched. This revision range could readily be used after a pull to look out
what's new with 'hg log'. The algorithm takes care of filtering "obsolete"
revisions that might be present in transaction's "changes" but should not be
displayed to the end user.
af9f7f376059 introduced a bug: emails Content-Transfer-Encoding
is silently replaced with 'quoted-printable' while any other
encoding could be used by underlying code. The problem is revealed
when a long unicode line is encoded.
The patch implements proper check which works for any text and
encoding.
Before this patch, kwweb_skip doesn't restore kwtemplater.match after
wrapped webcommands. This suppresses keyword expansion at wrapped
webcommands.
Typical usecase of this issue is "file" webcommand after annotate,
changeset, filediff or so on.
To ensure kwtemplater.match=util.never while original webcommand
running, this patch makes kwweb_skip yield values returned by it,
because it returns generator object.
Before this patch, kwdiff doesn't restore kwtemplater.restrict after
invocation of wrapped patch.diff(). This suppresses keyword expansion
at subsequent filelog.read().
Typical usecase of this issue is "hg cat" after "hg diff" with command
server. In this case, kwtemplater.restrict=True is kept in command
server process even after "hg diff".
To ensure kwtemplater.restrict=True while original patch.diff()
running, this patch makes kwdiff() yield values returned by it,
because it returns generator object.
Strictly speaking, if filelog.read() is invoked before completely
evaluating the result of previous patch.diff(), keyword expansion is
still suppressed, because kwtemplater.restrict isn't restored yet.
But this fixing should be reasonable enough, because patch.diff() is
consumed immediately, AFAIK.
We are about to remove the branchmap cache update in changegroup application.
There is a debug message alongside this update that we do not want to loose. We
move the message beforehand to simplify the test update in the next changeset.
The message move is quite noisy and isolating that noise is useful.
Most tests update are just line reordering since the message is issued at a
later point during the transaction.
After this changes, the message is displayed in more case since local commit
creation also issue it.
The way default marker template was defined before this patch,
the spacing before dash in conflict markes was dependent on
whether changeset is a tip one or not. This is a relevant part
of template:
'{ifeq(tags, "tip", "", "{tags} "}'
If revision is a tip revision with no other tags, this would
resolve to an empty string, but for revisions which are not tip
and don't have any other tags, this would resolve to a single
space string. In the end this causes weirdnesses like the ones
you can see in the affected tests.
This is a not a big deal, but double spacing may be visually
less pleasant.
Please note that test changes where commit hashes change are
the result of marking files as resolved without removing markers.
68ae3063a47d causes a fatal AttributeError if kwdemo is run outside a repo
because in the temporary repo creation repo is None and therefore cannot have a
baseui attribute.
In this case fall back to using ui.
Add test case.
Before this patch, "hg commit" (process A) executes steps below:
1. get current branch heads via 'repo.branchheads()'
- cache 'repo.changelog'
2. invoke 'repo.commit()'
3. acquire wlock
- invalidate 'repo.dirstate'
4. access 'repo.dirstate'
- re-read '.hg/dirstate'
- check validity of parent revisions with 'repo.changelog'
5. invoke 'repo.commitctx()'
6. acquire store lock (slock)
- invalidate 'repo.changelog'
7. do committing
8. release slock
9. release wlock
10. check new branch head (via 'cmdutil.commitstatus()')
If acquisition of wlock at (3) above waits for another "hg commit"
(process B) or so running parallelly to release wlock, process A
causes creating orphan revision, because:
- '.hg/dirstate' refers the revision, which is newly added by
process B, as its parent
- but already cached 'repo.changelog' doesn't contain such revision
- therefore, validating parents of '.hg/dirstate' at (4) above
replaces such revision with 'nullid'
Then, process A creates "orphan" revision, of which parent is "null"
revision.
In addition to it, "created new head" may be shown at the end of
process A unintentionally, if store is updated parallelly, because
both getting branch heads (1) and checking new branch head (10) are
executed outside slock scope.
To avoid this issue, this patch makes "hg commit" acquire wlock and
slock before processing.
This patch resolves the issue between "hg commit" processes, but not
one between "hg commit" and other commands. Subsequent patches resolve
the latter.
Even after this patch, there are still corner case problems below:
- filecache may overlook changes of '.hg/dirstate', and it causes
similar issue (see below for detail)
https://bz.mercurial-scm.org/show_bug.cgi?id=4368#c10
- 3rd party extension may cause similar issue, if it directly uses
'repo.commit()' without acquisition of wlock and slock
This can be fixed by acquisition of slock at the beginning of
'repo.commit()', but it seems suitable for "default" branch
In fact, acquisition of slock itself is already introduced at
"default" branch by ec227b188932, but acquisition is not at the
beginning of 'repo.commit()'.
This patch also changes some tests:
- test-fncache.t needs this tricky wrapping, to release (= forced
failure of) wlock certainly
- order of "hg commit" output is changed by widening scope of locks,
because some hooks are fired after releasing wlock
If detailed conflict markers are enabled and the closing quote gets truncated,
editors will often screw syntax highlighting up from that point because they'll
see an opening quote and think it's the beginning of a string.
In tests, the hashes change because the commit messages of the shelved bundles
also change.
The current output for a failed merge with conflict markers looks something like:
merging foo
warning: conflicts during merge.
merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
merging bar
warning: conflicts during merge.
merging bar incomplete! (edit conflicts, then use 'hg resolve --mark')
We're going to change the way merges are done to perform all premerges before
all merges, so that the output above would look like:
merging foo
merging bar
warning: conflicts during merge.
merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
warning: conflicts during merge.
merging bar incomplete! (edit conflicts, then use 'hg resolve --mark')
The 'warning: conflicts during merge' line has no context, so is pretty
confusing.
This patch will change the future output to:
merging foo
merging bar
warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
warning: conflicts while merging bar! (edit, then use 'hg resolve --mark')
The hint on how to resolve the conflicts makes this a bit unwieldy, but solving
that is tricky because we already hint that people run 'hg resolve' to retry
unresolved merges. The 'hg resolve --mark' mostly applies to conflict marker
based resolution.
$TESTDIR is added to the path, so this is superfluous. Also,
inconsistent use of quotes means we might have broken on tests with
paths containing spaces.
I tried to fix this issue in the past and had to revert the fix. This is a
second attempt without the regression we found with the first one.
record defines special headers (of file) as headers whose hunk are not shown
to the user for editing, they are used to represent deleted, moved and new
files. Since we want to authorize editing the patch of newly added file we
make the newly added file with some content not special anymore. This entails
that we have to save their content before applying the backup to be able to
revert it if the patch does not apply properly.
We reintroduce the test showing that newly added files can be edited and that
their content is shown to the user.
While using the record extension to select changes, the user couldn't see the
content of newly added files and had to select/reject them based on filename.
The test is changed accordingly in two places.
commitctx already showed notes with filenames but didn't provide any context.
It is just as relevant to know when manifest or changelog is committed.
So, in addition to filenames, also show headlines 'committing files:',
'committing manifest' and 'committing changelog'.
This patch makes bundrepo retract the phase boundary for new commits to 'draft'
status, which is consistent with the behavior of 'hg unbundle'. The old
behavior was for commits to appear with the same phase as their nearest
ancestor in the base repository.
This affects several classes of operation:
* Inspecting a bundle with the -B flag
* Treating a bundle file as a peer (old: everything public, new: everything draft)
* Incoming command (neither old or new behavior is sensible -- fixed in next patch)
Merged files are considered modified at commit time even if only 1 parent
differs. In this case we must use the change context of this parent for
expansion.
The issue went unnoticed for long because it is only apparent until the next
update to the merge revision - except in test-keyword where it was always
staring us in the face.
The tests often set ui.interactive to control normally interactive prompts from
stdin. That gave an output where it was non-obvious what prompts got which
which response, and the output lacked the newline users would see after input.
Instead, if the input not is a tty, write the selection and a newline.
We already have a ":" after the user name to denote the start of the
description. The current usage of quotes around the description is
problematic as the truncation to 80 chars is likely to drop the
closing quote. This may confuse syntax coloration in some editors.
Before this patch, 'hg fetch' may cause unexpected conflict, if 'hg
fetch'-ed changes are located near lines in which keywords are
embedded, because keywords are substituted with other strings in the
working directory.
This patch suppresses keyword expansion while 'hg fetch' for internal
merge by adding 'fetch' to 'restricted' command list like 'merge'.
This patch uses 'hg import' to safely create the new head to be merged
at succeeding 'hg fetch', because:
- branch of revision #10 is different from one of #11 in 'Test'
repository, so just 'hg fetch -r 11' doesn't cause merging between
them
this means the new head should be created manually.
- 'hg import' is easier and safer than 'cat <<EOF' and 'hg commit'
to replay same changes including special characters like '$'
safeness of 'hg import' with keyword extension is already examined
in 'test-keyword.t'.
Before this patch, 'hg histedit' may cause unexpected conflict, if 'hg
histedit'-ed changes are located near lines in which keywords are
embedded, because keywords are substituted with other strings in the
working directory.
This patch suppresses keyword expansion while 'hg histedit' for
internal merge by adding 'histedit' to 'restricted' command list like
'merge'.
Test in this patch just swaps order of revision #13 and #14: this is
enough to cause internal merge.
Before this patch, 'hg backout' may cause unexpected conflict, if 'hg
backout'-ed changes are located near lines in which keywords are
embedded, because keywords are substituted with other strings in the
working directory.
This patch suppresses keyword expansion while 'hg backout' for
internal merge by adding 'backout' to 'restricted' command list like
'merge'.
Before this patch, 'hg graft' may cause unexpected conflict, if 'hg
graft'-ed changes are located near lines in which keywords are
embedded, because keywords are substituted with other strings in the
working directory.
This patch suppresses keyword expansion while 'hg graft' for internal
merge by adding 'graft' to 'restricted' command list like 'merge'.
Before this patch, 'hg rebase' may cause unexpected conflict, if 'hg
rebase'-ed changes are located near lines in which keywords are
embedded, because keywords are substituted with other strings in the
working directory.
This patch suppresses keyword expansion while 'hg rebase' for internal
merge by adding 'rebase' to 'restricted' command list like 'merge'.
This patch specifies '--keep' to 'hg rebase', because revision #10 is
useful also for tests in succeeding patches.
Before this patch, 'hg unshelve' may cause unexpected conflict, if 'hg
unshelve'-ed changes are located near lines in which keywords are
embedded, because keywords are substituted with other strings in the
working directory.
This patch suppresses keyword expansion while 'hg unshelve' for
internal merge by adding 'unshelve' to 'restricted' command list like
'merge'.
Adds a conflict marker formatter that can produce custom conflict marker
descriptions. It can be set via ui.mergemarkertemplate. The old behavior
can be used still by setting ui.mergemarkers=basic.
The default format is similar to:
{node|short} {tag} {branch} {bookmarks} - {author}: "{desc|firstline}"
And renders as:
contextblahblah
<<<<<<< local: c7fdd7ce4652 - durham: "Fix broken stuff in my feature branch"
line from my changes
=======
line from the other changes
>>>>>>> other: a3e55d7f4d38 master - sid0: "This is a commit to master th...
morecontextblahblah
'export' is the official export format and used by patchbomb, but it would only
show date as a timestamp that most humans might find it hard to relate to. It
would be very convenient when reviewing a patch to be able to see what
timestamp the patch will end up with.
Mercurial has always used util.parsedate for parsing these headers. It can
handle 'all' date formats, so we could just as well use a readable one.
'export' will now use the format used by 'log' - which is the format described
as 'Unix date format' in the templating help. We assume that all parsers of '#
HG changeset patch'es can handle that.
The strip code used a trick to lower the cost of branchcache update after a
strip. However is less necessary since we have branchcache collaboration.
Invalid branchcache are likely to be cheaply rebuilt again a near subset of the
repo.
Moreover, this trick would need update to be relevant in the now filtered
repository world. It currently update the unfiltered branchcache that few people
cares about. Make it smarter on that aspect would need complexes update of the
calling logic
So this mechanism is:
- Arguably needed,
- Currently irrelevant,
- Hard to update
and I'm dropping it.
We now update the branchcache in all case by courtesy of the read only reader.
This changeset have a few expected impact on the testsuite are different cache
are updated.
The `commitctx` and `addchangegroup` methods of repo upgrade branchcache after
completion. This behavior aims to keep the branchcache in sync for read only
process as hgweb. See b4909adfc093 for details.
Since changelog filtering is used, those calls only update the cache for unfiltered repo.
One of no interest for typical read only process like hgweb.
Note: By chance in basic case, `repo.unfiltered() == repo.filtered('unserved')`
This changesets have the "unserved" cache updated instead. I think this is the
only cache that matter for hgweb.
We could imagine updating all possible branchcaches instead but:
- I'm not sure it would have any benefit impact. It may even increase the odd of
all cache being invalidated.
- This is more complicated change.
So I'm going for updating a single cache only which is already better that
updating a cache nobody cares about.
This changeset have a few expected impact on the testsuite are different cache
are updated.
Now that changelog filtering is in place, it's become evident that
naming the filters according to the set of revs _not_ included in the
filtered changelog is confusing. This is especially evident in the
collaborative branch cache scheme.
This changes the names of the filters to reflect the revs that _are_
included:
hidden -> visible
unserved -> served
mutable -> immutable
impactable -> base
repoview.filteredrevs is renamed to filterrevs, so that callers read a
bit more sensibly, e.g.:
filterrevs('visible') # filter revs according to what's visible
The dispatch code now enables filtering of "hidden" changesets globally. The
filter is installed before command and extension invocation. The `--hidden`
switch is now global and disables this filtering for any command.
Code in log dedicated to changeset exclusion is removed as this global filtering
has the same effect.
It filters all mutable changesets, leaving only public changeset unfiltered.
This filtering set is expected to be much more stable that the previous one as
public changeset are unlikely to disapear.
The only official use of this filter is for branchcache.
Filtered repository are *subset* of unfiltered repository. This means that a
filtered branchmap could be use to compute the unfiltered version.
And filtered version happen to be subset of each other:
- "all() - unserved()" is a subset of "all() - hidden()"
- "all() - hidden()" is a subset of "all()"
This means that branchmap with "unfiltered" filter can be used as a base for
"hidden" branchmap that itself could be used as a base for unfiltered
branchmap.
unserved < hidden < None
This changeset implements this mechanism. If the on disk branchcache is not valid
we use the branchcache of the nearest subset as base instead of computing it from
scratch. Such fallback can be cascaded multiple time is necessary.
Note that both "hidden" and "unserved" set are a bit volatile. We will add more
stable filtering in next changesets.
This changeset enables collaboration between no filtering and "unserved"
filtering. Fixing performance regression introduced by 7bff5f37cb97
When commit is followed by strip (qrefresh), phasecache contains nodes that were
removed from the changelog. Since phasecache is filecached with .hg/store/phaseroots
which doesn't change as a result of stripping, we have to filter it manually.
If we don't write it immediately, the next time it is read from disk the nodes
will be filtered again. That's what happened before, but there's no reason not
to write it immediately.
The change in test-keyword.t is caused by the above.
At this moment, the cache is invalid, and will be thrown away.
Later the strip function will call the `localrepo.destroyed` method
that will update the branchmap cache.
In several place, We check if a branchcache is still valid regarding the current
state of the repository. This changeset puts this logic in a method of the object
that can be reused when necessary.
A branch map is considered valid whenever it is up to date or a strict subset of
the repository state.
The change will help making branchcache aware of filtered revision.
The change in keyword is expected. the branch cache is actually invalid after
the amend. The previous check did not detected it.
Obsolescence cycle are bad and should be avoided as much as possible. The
current amend implemented touch changeset meta data as few as possible. This
make is easy for amend to result in the same node than a precursors. We add some
deterministic noise in extra to avoid this. In practice, the hex of the amended
changeset is stored in 'amend_source' extra key.