hggettext assumes that backslashes in docstring are always doubled in
original source code, in order to find the location of original
docstring out certainly.
This assumption almost always works as expected. But doctest easily
breaks it, because many of backslashes in doctests aren't doubled.
This mismatching causes "unknown offset in ..." warning at "make
update-pot".
To avoid such warning, this patch ignores doctest part of docstring
before finding the location of original docstring out.
BTW, at this patch, only person() in templatefilters.py has doctest
part, which causes "unknown offset ..." warning.
Therefore, just making backslashes in that doctest doubled can avoid
such warning, too. But forcing doctest writers to double backslashes
in doctest isn't reasonable, IMHO.
Before this patch, hggettext uses __doc__ of each functions to compute
offset of document text.
But __doc__ of many functions is already modified by decorators in
registrar (e.g. @templatekeyword adds ":NAME: " prefix to it), and
hggettext can not find it out in original source.
This causes many "unknown offset in ..." warning at "make update-pot",
and leaving them might cause overlooking serious problems.
This patch makes hggettext use original docstring, which decorators in
registrar save into _origdoc, to compute offset.
Even after this patch, there are still a few "unknown offset in ..."
warning at "make update-pot" for specific reasons. These will be fixed
later one by one.
The status line in the crecord has the "space" status field which has variable
length depending on the length of the status label in the language of choice.
In English, the status labels are "space: deselect" and "space:select". The
"deselect" label is 2 glyphs longer. This makes the terminal output jump
around if the terminal width is just right so that the shorter label makes
the status line 1 line long, and the longer label makes it 2 lines long.
This patch formats the selected status into a fixed-width field. The field
width is the maximum of the lengths of the two possible labels, to account for
differing translations and label lengths. This should make the label behavior
uniform across localizations.
There does not seem to be a test for crecord, so I verified the change manually
with a local build of 'hg'.
Our abstract interfaces are more useful if we guarantee that
implementations conform to certain rules. Namely, we want to ensure
that objects implementing interfaces don't expose new public
attributes that aren't part of the interface. That way, as long as
consumers don't access "internal" attributes (those beginning with
"_") then (in theory) objects implementing interfaces can be swapped
out and everything will "just work."
We add a test that enforces our "no public attributes not part
of the abstract interface" rule.
We /could/ implement "interface compliance detection" at run-time.
However, that is littered with problems.
The obvious solutions are custom __new__ and __init__ methods.
These rely on derived types actually calling the parent's
implementation, which is no sure bet. Furthermore, __new__ and
__init__ will likely be called before instance-specific attributes
are assigned. In other words, they won't detect public attributes
set on self.__dict__. This means public attribute detection won't
be robust.
We could work around lack of robust self.__dict__ public attribute
detection by having our interfaces implement a custom __getattribute__,
__getattr__, and/or __setattr__. However, this incurs an undesirable
run-time penalty. And, subclasses could override our custom
method, bypassing the check.
The most robust solution is a non-runtime test. So that's what this
commit implements. We have a generic function for validating that an
object only has public attributes defined by abstract classes. Then,
we instantiate some peers and verify a newly constructed object
plays by the rules.
Differential Revision: https://phab.mercurial-scm.org/D339
The wirepeer class provides concrete implementations of peer interface
methods for calling wire protocol commands. It makes sense for this
class to inherit from the peer abstract base class. So we change
that.
Since httppeer and sshpeer have already been converted to the new
interface, peerrepository is no longer adding any value. So it has
been removed. httppeer and sshpeer have been updated to reflect the
loss of peerrepository and the inheritance of the abstract base
class in wirepeer.
The code changes in wirepeer are reordering of methods to group
by interface.
Some Python code in tests was updated to reflect changed APIs.
.. api::
peer.peerrepository has been removed. Use repository.peer abstract
base class to represent a peer repository.
Differential Revision: https://phab.mercurial-scm.org/D338
We need the same @property conversion of ui like we did for localpeer.
We renamed _capabilities() to capabilities() to satisfy the new
naming requirement.
However, since we're inheriting from wireproto.wirepeer which inherits
from peer.peerrepository and provides its own code accessing
_capabilities(), we need to keep the old alias around. This wonkiness
will disappear once wirepeer is cleaned up in subsequent commits.
We also implement methods for basepeer that are identical to the
defaults in peer.peerrepository in preparation for the removal of
peerrepository.
Differential Revision: https://phab.mercurial-scm.org/D336
We now have a formal abstract base class for peers. Let's
transition the peer classes in localrepo to it.
As part of the transition, we reorder methods so they are grouped
by interface and match the order they are defined in the interface.
We also had to change self.ui from an instance attribute to a
property to satisfy the @abstractproperty requirement.
As part of this change, we uncover the first "bug" as part of
enforcing interfaces: stream_out() wasn't implemented on localpeer!
This isn't technically a bug since the repo isn't advertising the
stream capability, so clients shouldn't be attempting to call it.
But I don't think there's a good reason why this is the case.
We implement a dummy method to satisfy the interface requriements.
We can make localpeer instances streamable as a future enhancement.
# no-check-commit
Differential Revision: https://phab.mercurial-scm.org/D335
These methods are part of the peer interface, are generic, and can
be implemented in terms of other members of the peer interface. So we
implement them on the peer base class as a convenience.
The implementation is essentially copied from peer.py. The code
in peer.py will eventually be deleted.
Differential Revision: https://phab.mercurial-scm.org/D334
There are a well-defined set of commands constituting the wire
protocol. Interaction with these and methods for calling them in
batches are exposed via methods on peer instances.
Let's formalize support for these features in abstract classes.
The command parts come from the existing wireproto.wirepeer class.
The batch methods come from peer.peerrepository.
Ample documentation has been added as part of defining the interfaces.
# no-check-commit
Differential Revision: https://phab.mercurial-scm.org/D333
There are various interfaces for interacting with repositories
and peers. They form a contract for how one should interact with
a repo or peer object.
The contracts today aren't very well-defined or enforced. There
have been several bugs over the years where peers or repo types
have forgotten to implement certain methods. In addition, the
inheritance of some classes is wonky. For example, localrepository
doesn't inherit from an interface and the god-object nature of
that class means the repository interface isn't well-defined. Other
repository types inherit from localrepository then stub out
methods that don't make sense (e.g. statichttprepository
re-defining locking methods to fail fast).
Not having well-defined interfaces makes implementing alternate
storage backends, wire protocol transports, and repository types
difficult because it isn't clear what exactly needs to be
implemented.
This patch starts the process of attempting to establish more
order to the type system around repositories and peers.
Our first patch starts with a problem space that already has a
partial solution: peers. The peer.peerrepository class already
somewhat defines a peer interface. But it is missing a few things
and the total interface isn't well-defined because it is combined
with wireproto.wirepeer.
Our newly-established basepeer class uses the abc module to
declare an abstract base class with the properties and methods that
a generic peer must implement.
We create a new class that inherits from it. This class will hold
our other future abstract base classes / interfaces so we can expose
a unified base class/interface.
We don't yet use the new interface because subsequent additions
will break existing code without some refactoring first.
A new module (repository.py) was created to hold the interfaces.
I could have put things in peer.py. However, I have plans to
eventually add interfaces to define repository and storage types.
These almost certainly require a new module. And I figured having
all the interfaces live in one module makes sense. So I created
repository.py to be that future home.
Differential Revision: https://phab.mercurial-scm.org/D332
a3022f57803b made `util.nogc` a no-op. It was to optimize PyPy. But it slows
down CPython if many objects (like 300k+) are created.
For example, running `hg log -r .` without extensions in `hg-committed` with
14k+ obsmarkers have the following times:
before | after
hg | chg | hg | chg
-----------------------------
1.262 | 0.860 | 1.077 | 0.619 (seconds, best of 20 runs)
Therefore let's re-enable nogc for CPython.
Differential Revision: https://phab.mercurial-scm.org/D402
troubled has been renamed into isunstable but troubled was calling unstable
instead. Fix the mistake.
Differential Revision: https://phab.mercurial-scm.org/D384
Invoking *.sh on Windows leads to the "what program should open this?" prompt,
which stalls the test and led to the recent series of exceptions on the Windows
test machine as the runner times out.
We have at least three types with a close() and a release() method
where the close() method is supposed to be called on success and the
release() method is supposed to be called last, whether successful or
not. Two of them (transaction and dirstateguard) already have
identical implementations of __enter__ and __exit__. Let's extract a
base class for this, so we reuse the code and so the third type
(transactionmanager) can also be used as a context manager.
Differential Revision: https://phab.mercurial-scm.org/D392
The transactionmanager() constructor just assigned a few variables and
cannot fail, so it's safe to move it inside the earlier try/except.
Differential Revision: https://phab.mercurial-scm.org/D391
Since 6f17bd68a306 (exchange: drop support for lock-based unbundling
(BC), 2017-08-06), there is no more remote locking.
Differential Revision: https://phab.mercurial-scm.org/D390
The variable has been used only within a single function since
5d683cc9670f (push: elevate phase transaction to cover entire
operation, 2014-11-21), so there's no need to keep it on the pushop
object.
Differential Revision: https://phab.mercurial-scm.org/D389
The old error message "cannot use revision REV as base, result would have 3
parents" is confusing - why use REV as base? why add a new parent?.
This patch changes it to "cannot move parent", which seems better.
Differential Revision: https://phab.mercurial-scm.org/D342
Previously `hg phabsend` was imitating `hg email` and won't mutate
changesets. That works fine with reviewer-push workflow, reviewers run
`phabread`, `import`.
However, it does not work well with author-push workflow. Namely, the author
needs to run extra commands to get the right commit message, and remove the
local tag after push.
This patch solves those issues by adding the `--amend` option, so local
changesets will have the right commit message, and tags become unnecessary.
Test Plan:
Given the following DAG:
o 17
o 16
| o 15
| @ 14
|/
o 13
o 12
Run `hg phabsend '(13::)-17' --amend`, check the new DAG looks like:
o 21
| o 20
| @ 19
|/
o 18
| o 17
| x 16
| x 13
|/
o 12
And commit messages are updated to contain the `Differential Revision` lines.
Use `phabread` to make sure Phabricator has the amended node recorded.
Also check `phabsend .` followed by a `phabsend . --amend`, the commit
message will be updated and the tag will be removed.
Differential Revision: https://phab.mercurial-scm.org/D122
"defineparents" is the core algorithm of rebase. The old code has too many
tech debts (like outdated comments, confusing assertions, etc) and is very
error-prone to be improved. This patch rewrites "defineparents" to make the
code easier to reason about, and solve a bunch of issues, including:
- Assertion error: no base found (demonstrated by D212, issue5578)
- Asymmetric result (demonstrated by D211, "F with one parent")
- Wrong new parent (demonstrated by D262, "C':A'A'")
- "revlog index out of range" (demonstrated by D262, issue5630)
- "nothing to merge" (demonstrated by D262)
As a side effect, merge base decision has been made more solid - rebase now
prints out explicitly what could go wrong when it cannot find a unique
suitable merge base.
.. fix:: Issue 5578, Issue 5630
Core rebase algorithm has been rewritten to be more robust.
Differential Revision: https://phab.mercurial-scm.org/D21
evolution* config has been rewritten in stabilization* in the previous patch,
update tests file to use the new names.
Differential Revision: https://phab.mercurial-scm.org/D249
morestatus extension in fbext use to show more context about the state of the
repo like the repository is in a unfinished merge state, or a rebase is going
on, or histedit is going on, listing the files which need to be resolved and
also suggesting ways to handle the situation.
This patch moves the extension directly to core by plugging it into the
--verbose flag of the status command. So now if you are in any unfinished state
and you do hg status -v, it will show you details and help related to the state.
The extension in fbext also shows context about unfinished update state
which is not ported to core as that plug in hooks to update command which need
to be tackled somewhat differently.
The following configuration will turn the behaviour on by default
[commands]
status.verbose = 1
You can also skip considering some states like bisect as follows:
[commands]
status.skipstates=bisect
This patch also adds test for the feature.
.. feature::
``hg status -v`` can now show unfinished state. For example, when in
an unfinished rebase state, ``hg status -v`` might show::
# The repository is in an unfinished *rebase* state.
# No unresolved merge conflicts.
# To continue: hg rebase --continue
# To abort: hg rebase --abort
Differential Revision: https://phab.mercurial-scm.org/D219
Changeset aa97e972460f introduce more complex logic around
'bundleoperation.gettransaction'. In that process it turns the old "attribute"
into a proper method which breaks the code that detects the "transaction
availability".
The change was visible in 'test-acl.t', fixing this reverts the test changes.
Differential Revision: https://phab.mercurial-scm.org/D303
Without the change, the error looks like:
warning: Watchman unavailable: "watchman" executable not in PATH (%s),
while executing [Errno 2] No such file or directory
With the change, it now looks like:
warning: Watchman unavailable: "watchman" executable not in PATH
([Errno 2] No such file or directory)
Differential Revision: https://phab.mercurial-scm.org/D322
Peer types are supposed to conform to a formal interface defined by
peer.peerrepository and wireproto.wirepeer. Every "public" attribute on
*peer types makes it harder to understand what attributes are part
of the interface and what are instance specific.
This commit converts a number of "public" instance attributes and
methods on sshpeer to internal so they can't be confused to be part of
the peer API.
The URL-related instance attributes were introduced in 904c418bea16
in 2005. AFAICT most of them aren't used and could potentially be
removed. But I kept them around anyway.
I also reorded some code to make things slightly easier to read.
.. api::
Rename attributes on sshpeer to reflect peer API
Differential Revision: https://phab.mercurial-scm.org/D331