Commit Graph

18253 Commits

Author SHA1 Message Date
Yuya Nishihara
c11e91f8ff pager: use less as a fallback on Unix
This seems reasonable choice per discussion, and the default-default of Git.
See also the inline-comment for why.

https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-April/097042.html
2017-04-28 20:51:14 +09:00
Matt DeVore
212fc81929 help: explain how to access subtopics in internals 2017-04-19 17:04:22 -07:00
Matt DeVore
2eace305ec log: document the characters ---graph uses to draw
The meaning of : vs | was undocumented and non-obvious.
2017-04-18 14:51:32 -07:00
Denis Laxalde
82be200bb6 hgweb: change text of followlines links to "older / newer"
DAG directions "descending" / "ascending" arguably do not make much sense in
the web interface where changes are usually listed by "dates".
2017-04-24 10:48:07 +02:00
Denis Laxalde
d141711562 hgweb: do not show "descending" link in followlines UI for filelog heads
When on a filelog head, we are certain that there will be no descendant so the
target of the "descending" link will lead to an empty log result. Do not
display the link in this case.
2017-04-24 10:32:15 +02:00
Denis Laxalde
d7d47fec65 context: optimize linkrev adjustment in blockancestors() (issue5538)
We set parent._descendantrev = child.rev() when walking parents in
blockancestors() so that, when linkrev adjustment is perform for these, it
starts from a close descendant instead of possibly topmost introrev. (See
`self._adjustlinkrev(self._descendantrev)` in filectx._changeid().)

This is similar to changeset 8758896efb1c, which added a "f._changeid"
instruction in annotate() for the same purpose.
However, here, we set _descendantrev explicitly instead of relying on the
'_changeid' cached property being accessed (with effect to set _changeid
attribute) so that, in _parentfilectx() (called from parents()), we go through
`if '_changeid' in vars(self) [...]` branch in which instruction
`fctx._descendantrev = self.rev()` finally appears and does what we want.

With this, we can roughly get a 3x speedup (including in example of issue5538
from mozilla-central repository) on usage of followlines revset (and
equivalent hgweb request).
2017-04-24 18:33:23 +02:00
Boris Feld
46290fc257 record: update help message to use operation instead of "record" (issue5432)
Update the hunk selector help message to use the operation name instead
of using "record" for all operations. Extract the help message in the same way
as other single and multiple message line.
Update tests to make sure that both "revert" and "discard" variants are tested.
2017-04-24 17:13:24 +02:00
Denis Laxalde
7cc06d2fbf context: start walking from "introrev" in blockancestors()
Previously, calling blockancestors() with a fctx not touching file would
sometimes yield this filectx first, instead of the first "block ancestor",
because when compared to its parent it may have changes in specified line
range despite not touching the file at all.

Fixing this by starting the algorithm from the "base" filectx obtained using
fctx.introrev() (as done in annotate()).

In tests, add a changeset not touching file we want to follow lines of to
cover this case. Do this in test-annotate.t for followlines revset tests and
in test-hgweb-filelog.t for /log/<rev>/<file>?linerange=<from>:<to> tests.
2017-04-20 21:40:28 +02:00
Augie Fackler
2f7c844e98 sshpeer: try harder to snag stderr when stdout closes unexpectedly
Resolves test failures on FreeBSD, but I'm not happy about the fix.

A previous version of this also wrapped readline by putting the hack
in the _call method on doublepipe. That was confusing for readers and
wasn't necessary - just doing this on read() is sufficient to fix the
bugs I'm observing. We can always come back and do readline later if
needed.
2017-04-13 16:09:40 -04:00
Gregory Szorc
1c728c872c show: add basic labels to work template
`hg show work` is much more usable if output is colored. This patch
implements coloring via label() in a very hacky way.

In a default Mercurial install, you'll see yellow node labels for all
phases. Branches and bookmarks use the same formatting as the commit
message. So this change doesn't help much in a default install. But if
you have a custom colors defined for these things, output is much more
readable.

The implementation obviously needs some work. But for a minor change
on a feature that isn't convered by BC, this seems like a clear win
for the feature in 4.2.
2017-04-18 11:10:08 -07:00
Gregory Szorc
a0449ff50c show: rename "underway" to "work"
Durham and I both like this better than "underway." We can add aliases
and bikeshed on the name during the 4.3 cycle, as this whole extension is
highly experimental.
2017-04-18 10:49:46 -07:00
Augie Fackler
3d0bf6c892 freeze: merge default into stable for 4.2 code freeze 2017-04-18 12:24:34 -04:00
Augie Fackler
78231e34ab Merge stable with security patch. 2017-04-18 11:22:42 -04:00
Yuya Nishihara
e76c15f04b progress: retry ferr.flush() and .write() on EINTR (issue5532)
See the inline comment how this could mitigate the issue.

I couldn't reproduce the exact problem on my Linux machine, but there are
at least two people who got EINTR in progress.py, and it seems file_write()
of Python 2 is fundamentally broken [1]. Let's make something in on 4.2.

 [1]: https://hg.python.org/cpython/file/v2.7.13/Objects/fileobject.c#l1850
2017-04-13 22:31:17 +09:00
Yuya Nishihara
71733ed667 progress: extract stubs to restart ferr.flush() and .write() on EINTR 2017-04-13 22:27:25 +09:00
Augie Fackler
b2bd435955 dispatch: protect against malicious 'hg serve --stdio' invocations (sec)
Some shared-ssh installations assume that 'hg serve --stdio' is a safe
command to run for minimally trusted users. Unfortunately, the messy
implementation of argument parsing here meant that trying to access a
repo named '--debugger' would give the user a pdb prompt, thereby
sidestepping any hoped-for sandboxing. Serving repositories over HTTP(S)
is unaffected.

We're not currently hardening any subcommands other than 'serve'. If
your service exposes other commands to users with arbitrary repository
names, it is imperative that you defend against repository names of
'--debugger' and anything starting with '--config'.

The read-only mode of hg-ssh stopped working because it provided its hook
configuration to "hg serve --stdio" via --config parameter. This is banned for
security reasons now. This patch switches it to directly call ui.setconfig().
If your custom hosting infrastructure relies on passing --config to
"hg serve --stdio", you'll need to find a different way to get that configuration
into Mercurial, either by using ui.setconfig() as hg-ssh does in this patch,
or by placing an hgrc file someplace where Mercurial will read it.

mitrandir@fb.com provided some extra fixes for the dispatch code and
for hg-ssh in places that I overlooked.
2017-04-12 11:23:55 -07:00
Gregory Szorc
34d4f7ff46 repair: use rawvfs when copying extra store files
If we use the normal vfs, store encoding will be applied when we
.join() the path to be copied. This results in attempting to copy
a file that (likely) doesn't exist. Using the rawvfs operates on
the raw file path, which is returned by vfs.readdir().

Users at Mozilla are encountering this, as I've instructed them to
run `hg debugupgraderepo` to upgrade to generaldelta. While Mercurial
shouldn't deposit any files under .hg/store that require encoding, it
is possible for e.g. .DS_Store files to be created by the operating
system.
2017-04-08 11:36:39 -07:00
Gregory Szorc
a205e76c91 repair: iterate store files deterministically
An upcoming test will add a 2nd file. Since readdir() is
non-deterministic, add a sorted() to make traversal deterministic.
2017-04-08 11:35:00 -07:00
Gregory Szorc
6fb64a9cca changegroup: store old heads as a set
Previously, the "oldheads" variable was a list. On a repository at
Mozilla with 46,492 heads, profiling revealed that list membership
testing was dominating execution time of applying small changegroups.

This patch converts the list of old heads to a set. This makes
membership testing significantly faster. On the aforementioned
repository with 46,492 heads:

$ hg unbundle <file with 1 changeset>
before: 18.535s wall
after:   1.303s

Consumers of this variable only check for truthiness (`if oldheads`),
length (`len(oldheads)`), and (most importantly) item membership
(`h not in oldheads` - which occurs twice). So, the change to a set
should be safe and suitable for stable.

The practical effect of this change is that changegroup application
and related operations (like `hg push`) no longer exhibit an O(n^2)
CPU explosion as the number of heads grows.
2017-03-23 19:54:59 -07:00
Simon Farnsworth
ddbe7287e7 subrepo: move prompts out of the if (issue5505)
Prompts weren't available in the else clause
2017-03-20 04:36:55 -07:00
Gregory Szorc
aff9286eb0 exchange: use v2 bundles for modern compression engines (issue5506)
Previously, `hg bundle zstd` on a non-generaldelta repo would
attempt to use a v1 bundle. This would fail because zstd is not
supported on v1 bundles.

This patch changes the behavior to automatically use a v2 bundle
when the user explicitly requests a bundlespec that is a compression
engine not supported on v1. If the bundlespec is <engine>-v1, it is
still explicitly rejected because that request cannot be fulfilled.
2017-03-16 12:33:15 -07:00
Gregory Szorc
3bbb6e2c52 exchange: reject new compression engines for v1 bundles (issue5506)
Version 1 bundles only support a fixed set of compression engines.
Before this change, we would accept any compression engine for v1
bundles, even those that may not work on v1. This could lead to
an error.

We define a fixed set of compression engines known to work with v1
bundles and we add checking to ensure a newer engine (like zstd)
won't work with v1 bundles.

I also took the liberty of adding test coverage for unknown compression
names because I noticed we didn't have coverage of it before.
2017-03-16 12:23:56 -07:00
Augie Fackler
5811358454 pycompat: verify sys.argv exists before forwarding it (issue5493)
ISAPI_WSGI doesn't set up sys.argv, so we have to look for the
attribute before assuming it exists.
2017-03-07 13:24:24 -05:00
Yuya Nishihara
8af2b4d601 filemerge: optionally strip quotes from merge marker template (BC)
For consistency with the other template options. Quotes are necessary if
you want to preserve leading/trailing whitespace, which would be stripped
by config parser.
2017-02-25 19:36:02 +09:00
Yuya Nishihara
9466c3179f commit: optionally strip quotes from commit template (BC)
For consistency with the other template options.
2017-02-25 19:32:39 +09:00
Yuya Nishihara
5fbb2d3cd5 graphlog: optionally strip quotes from graphnode template (BC)
For consistency with the other template options.
2017-02-25 19:28:16 +09:00
Yuya Nishihara
649f9bf987 dispatch: ignore further SIGPIPE while handling KeyboardInterrupt
I got the following error by running "hg log" and quitting the pager
immediately. Any output here may trigger another SIGPIPE, so only thing
we can do is to swallow the exception and exit with an error status.

  Traceback (most recent call last):
    File "./hg", line 45, in <module>
      mercurial.dispatch.run()
    File "mercurial/dispatch.py", line 83, in run
      status = (dispatch(req) or 0) & 255
    File "mercurial/dispatch.py", line 167, in dispatch
      req.ui.warn(_("interrupted!\n"))
    File "mercurial/ui.py", line 1224, in warn
      self.write_err(*msg, **opts)
    File "mercurial/ui.py", line 790, in write_err
      self._write_err(*msgs, **opts)
    File "mercurial/ui.py", line 798, in _write_err
      self.ferr.write(a)
    File "mercurial/ui.py", line 129, in _catchterm
      raise error.SignalInterrupt
  mercurial.error.SignalInterrupt

Perhaps this wasn't visible before ee4f321cd621 because the original stderr
handle was restored very late.
2017-04-17 23:53:19 +09:00
Yuya Nishihara
b132ffa375 worker: print traceback for uncaught exception unconditionally
This is what a Python interpreter would do if there were no os._exit().
2017-04-15 13:04:55 +09:00
Yuya Nishihara
7144ff068f worker: propagate exit code to main process
Follows up 560cc0db7f01.
2017-04-15 13:27:44 +09:00
Yuya Nishihara
aabbe05fb5 dispatch: print traceback in scmutil.callcatch() if --traceback specified
Otherwise, traceback wouldn't be printed for a known exception occurred in
worker processes.
2017-04-15 13:02:34 +09:00
Yuya Nishihara
1ea92e7f19 dispatch: mark callcatch() as a private function 2017-04-15 12:58:06 +09:00
Yuya Nishihara
e952ac99ea templatefilters: fix crash by string formatting of '{x|splitlines}'
Before, it crashed because mapping['templ'] was missing. As it didn't support
the legacy list template from the beginning, we can simply use hybridlist().
2017-04-15 10:51:17 +09:00
Yuya Nishihara
3a01d624e0 templatekw: factor out showdict() helper
Make it less cryptic for common cases.
2017-04-05 21:57:05 +09:00
Yuya Nishihara
e83ec90299 templatekw: have showlist() take mapping dict with no **kwargs expansion (API)
See the previous commit for why.

splitlines() does not pass a mapping dict, which would probably mean the
legacy template didn't work from the beginning.
2017-04-05 21:47:34 +09:00
Yuya Nishihara
14174e42d0 templatekw: change _showlist() to take mapping dict with no **kwargs expansion
There was a risk that a template keyword could conflict with an argument
name (e.g. 'name', 'values', 'plural', etc.) Let's make it less magical.
2017-04-05 21:40:38 +09:00
Yuya Nishihara
e7f0402cb5 templatekw: rename 'args' to 'mapping' in showlist()
The name 'args' provides no information. Call it 'mapping' as in templater.py.
2017-04-05 21:32:32 +09:00
Yuya Nishihara
ae7c681de5 templatekw: eliminate unnecessary temporary variable 'names' from _showlist()
Replace 'names' with the optional argument 'plural'.
2017-04-05 21:27:44 +09:00
Pierre-Yves David
257e9cf217 color: update the help with the new default
The default is now "auto" we update the help to match reality.
2017-04-17 20:22:00 +02:00
Pierre-Yves David
c9ad04b92a upgrade: register all format variants in a list
Now that all known format variants exists outside of the function, we can gather
them in a lists. This build a single entry point other code can use (current
target: extensions).

The repository upgrade code is updated to simply use entries from this list.

As a side effect this will also allow extensions to register their own format
variants, to do this "properly" we should introduce a "registrar" for this
category of object. However I prefer to keep this series simple, and that will
be adventure for future time.
2017-04-12 16:48:13 +02:00
Pierre-Yves David
1d4581993a upgrade: move descriptions and selection logic in individual classes
Our goal here is to get top level definition for all the format variants. Having
them defined outside of the function enabled other users of that logic.

They are two keys components of a format variant:

1) the name and various descriptions of its effect,

2) the code that checks if the repo is using this variant and if the config
   enables it.

That second items make us pick a class-based approach, since different variants
requires different code (even if in practice, many can reuse the same logic).
Each variants define its own class that is then used like a singleton.  The
class-based approach also clarify the definitions part a bit since each are
simple assignment in an indented block.

The 'fromdefault' and 'fromconfig' are respectively replaced by a class
attribute and a method to be called at the one place where "fromconfig"
matters.

Overall, they are many viable approach for this, but this is the one I picked.
2017-04-12 16:34:05 +02:00
Pierre-Yves David
62412d4eb9 upgrade: introduce a 'formatvariant' class
The 'deficiency' type has multiple specificities. We create a dedicated class to
host them. More logic will be added incrementally in future changesets.
2017-04-10 23:34:43 +02:00
Pierre-Yves David
285b20d327 upgrade: implement '__hash__' on 'improvement' class
The pythonomicon request its implementation.
2017-04-17 13:07:31 +02:00
Pierre-Yves David
258609b002 upgrade: implement '__ne__' on 'improvement' class
The pythonomicon request its implementation.
2017-04-17 13:07:22 +02:00
Pierre-Yves David
97de39f32f color: also enable by default on windows
I've not found anything related to color + windows on the bug tracker. So I'm
suggesting we get bolder and turn it on for windows too in the release
candidate. We can always backout this changeset if we find serious issue on
windows.
2017-04-16 02:34:08 +02:00
Pierre-Yves David
1a7077c9d6 color: turn on by default (but for windows)
Color support is all in core for a couple of months. I've browsed the bug tracker
without finding any blocker bug. So I'm moving forward and enable color on by
default before '4.2-rc'. In the worse case, having it on in the release
candidate will help us to find blocker bug and we can turn it off for the final
release.

I remember people talking about issue with Windows during the freeze so I'm
keeping it off by default on that OS.

We could do various cleaning of the color used and the label issued.  However
the label are probably already in our backward compatibility envelope since the
color extensions has been around since for ever and I do not think the color
choice themself should be considered BC. So I think we should rather gives color
to all user sooner than later.

A couple of test needs to be updated to avoid having color related control code
spoil the tested output.
2017-04-16 02:32:51 +02:00
Gregory Szorc
79225ac4bc bundle2: ignore errors seeking a bundle after an exception (issue4784)
Many have seen a "stream ended unexpectedly" error. This message is
raised from changegroup.readexactly() when a read(n) operation fails
to return exactly N bytes.

I believe most occurrences of this error in the wild stem from
the code changed in this patch. Before, if bundle2's part applicator
raised an Exception when processing/applying parts, the exception
handler would attempt to iterate the remaining parts. If I/O
during this iteration failed, it would likely raise the
"stream ended unexpectedly" exception.

The problem with this approach is that if we already encountered
an I/O error iterating the bundle2 data during application, then
any further I/O would almost certainly fail. If the original stream
were closed, changegroup.readexactly() would obtain an empty
string, triggering "stream ended unexpectedly" with "got 0." This is
the error message that users would see. What's worse is that the
original I/O related exception would be lost since a new exception
would be raised. This made debugging the actual I/O failure
effectively impossible.

This patch changes the exception handler for bundle2 application to
ignore errors when seeking the underlying stream. When the underlying
error is I/O related, the seek should fail fast and the original
exception will be re-raised. The output changes in
test-http-bad-server.t demonstrate this.

When the underlying error is not I/O related and the stream can be
seeked, the old behavior is preserved.
2017-04-16 11:55:08 -07:00
Gregory Szorc
6b50f59909 error: rename RichIOError to PeerTransportError
This is a more descriptive name. RichIOError was introduced just
hours ago, so it doesn't need to be marked as BC.
2017-04-16 11:12:37 -07:00
Gregory Szorc
4f9cd469df httppeer: don't send empty Vary request header
As part of writing test-http-bad-server.t, I noticed that some
requests include an empty Vary HTTP request header.

The Vary HTTP request header indicates which headers should be taken
into account when determining if a cached response can be used. It also
accepts the special value of "*".

The previous code unconditionally added a Vary header. This could lead
to an empty header value. While I don't believe this violates the HTTP
spec, this is weird and just wastes bytes. So this patch changes
behavior to only send a Vary header when it has a value.

Some low-level wire protocol byte reporting tests changed. In some
cases, the exact point of data termination changed. However, the
behavior being tested - that clients react when the connection is
closed in the middle of an HTTP request line or header - remains
unchanged.
2017-04-16 11:28:02 -07:00
Pierre-Yves David
551d0f8ee6 checkheads: upgrade the obsolescence postprocessing logic (issue4354)
The previous logic had many shortcoming (eg: looking at the head only, not
handling prune, etc...), the new logic use a more robust approach:

For each head, we check if after the push all changesets exclusive to this heads
will be obsolete. If they are, the branch considered be "replaced".

To check if a changeset will be obsolete, we simply checks:

* the changeset phase

* the existence of a marker relevant to the "pushed set" that affects the
  changesets..

This fixes two major issues of the previous algorithm:

* branch partially rewritten (eg: head but not root) are no longer detected as
  replaced,

* Prune are now properly handled.

(This implementation was introduction in the evolve extension, version 6.0.0.)

This new algorithm has an extended number of tests, a basic one is provided
in this patch. The others will be introduced in their own changeset for clarity.

In addition, we stop trying to process heads unknown locally, we do not have
enough data to take an informed decision so we should stop pretending we do.
This reflect a test that is now update.
2017-04-15 02:55:18 +02:00
Pierre-Yves David
d03144db9c hidden: extract the code generating "filtered rev" error for wrapping
The goal is to help experimentation in extensions (ie: evolve) around more
advance messages.
2017-04-15 18:13:10 +02:00