Previously, histedit.cleanupnode pass root nodes one by one. Since
repair.strip takes multiple nodes and can handle them just fine, pass all
strip roots at once.
This is BC because the number of strip backup files may change from N to 1.
histedit treats topmost bookmark movement specially. The rest of the
bookmark movement could be handled by scmutil.cleanupnodes. So let's move
the special logic out to make the patch easier to review.
This is more consistent with other commands, like "commit -v" won't show
bookmark movement messages.
It will make migrating to scmutil.cleanupnodes easier.
This is one step towards removing a bunch of "if isinstance(gen,
unbundle20)" by treating bundle1 and bundle2 more similarly.
The name may sounds ironic for a method in the bundle2 module, but I
didn't think it was worth it yet to create a new 'bundle' module that
depends on the 'bundle2' module. Besides, we'll inline the method
again later.
cmdutil.command wasn't a member of the registrar framework only for a
historical reason. Let's make that happen. This patch keeps cmdutil.command
as an alias for extension compatibility.
By recording what operation created the obsmarker, we can show very intuitive
messages to the user in various UIs. For instance, log output could have
messages like "Amended as XXX" to show why a commit is old and has an 'x' on it.
@ ac28e3 durham
/ First commit
|
| o d4afe7 durham
| | Second commit
| |
| x 8e9a5d (Amended as ac28e3) durham
|/ First commit
|
Previously, we'd rely on the implicit check that `localrepo.commit` did.
The problem is that that check only happened when the working copy was
dirty. With a "clean" working copy but unresolved conflicts we'd get
into a broken state.
To fix that, do what rebase does and check for unresolved conflicts at
the start of histedit --continue.
Before 33e44341bb82, histedit (like rebase) was only creating markers on final
success from the old-rewritten node to the newly created nodes (as of before
33e44341bb82). In case of abort the aborted attempt were stripped to restore the
repository in its state prior to the attempt.
This use of strip was on purpose. Using markers in this case introduces various
issues. The main one is that keeping the partial result of histedit as obsolete
prevents us to recreates the same nodes in a second attempt. The same operation
will lead to an identical results, using an identical node that already exists
in the repository as obsolete.
To conclude, we cannot and should not switch to obsolescence markers creation on
histedit --abort and we backout 33e44341bb82. A test to catch this class of
issue will be introduced in the next changeset.
Move "cleanupnode" (unsafe strip) into "safecleanupnode" so it's impossible
to call the unsafe function directly.
This helps reduce future programming errors.
The new method will decide between:
- cleanupnode, which calls the unsafe repair.strip
- create obsmarkers
Ideally, nobody calls "cleanupnode" directly except for "safecleanupnode".
This adds an option (which defaults to False) to run entire histedits in a
single transaction. This results in 20-25% faster histedits in large repos where
transaction startup cost is expensive.
I didn't want to enable this by default because it has some unfortunate side
effects. For instance, if a pretxncommit hook throws midway through the
histedit, it will rollback the entire histedit and lose any progress the user
had made. Same if the user aborts editting a commit message. It's still worth
turning this on for large repos, but probably not for normal sized repos.
Long term, once we have inmemory merging, we could do the entire histedit in
memory, without a transaction, then we could selectively rollback just parts of
it in the event of an exception.
Tested it by running the tests with
`--extra-config-opt=histedit.singletransaction=True`. The only failure was
related to the hook rollback issue I mention above.
We only want to pop the action after the action is completed, since if the
action aborts part way through we want it to remain at the front of the list so
continue/abort will start with it.
Previously we relied on the fact that we only serialized the state file at the
beginning of the action, so the pop wasn't serialized until the next iteration
of the loop. In a future patch we will be adding a large transaction around this
area, which means if we pop the list early it might get serialized if the action
throws a user InterventionRequired error, at which point the action is not in
the list anymore. So let's only pop it once the action is really truly done.
This change adjusts and documents the new behaviour of 'roll'. It now fits nicely
with the behaviour of 'commit --amend' and the 'edit' action, by discarding the
date as well as the commit message of the second commit. Previously it used the
later date, like 'fold', but this often wasn't desirable, for example, in the
common use case of using 'roll' to add forgotten changes to a changeset
(because 'hg add' was previously forgotten or not all changes were identified
while using 'hg record').
This clarifies in the histedit documentation that the 'edit' action preserves
the date and that the 'fold' action uses the later date. The documentation was
previously silent on this issue which left users in doubt.
All actions but one actually have the same constraints when it comes to validate
the 'action.node' value. So we actually just add this code to a method that can
be overwritten in the one action where it matters.
The now unused 'contraints' related enum and class attribute will be cleaned up
in the next changeset.
Action has a method dedicated to verifying its validity. So we move code
related to constrains into that method. This requires a bit more context to the
'verify' method in the same fashion we were passing the 'prev' argument.
This is an extra step before we can simplify the constraint handling code
further.
It does not seem useful to convert to hex: it is an extra step and they are
longer strings. So we stick to node for the logic. We only convert to short hex
for error when needed. As a nice side effect this remove the explicit constant
usage in'[12:]'. This will also help moving the code around later as we just
have to access action.node.
An upcoming changeset will make the line where this variable is used
slightly too long. Other later changesets will clean that up further and makes
the variable unnecessary, so this is only temporary and it does seems useful to
put anything more complicate in place.
There does not seem to be a reason for this to be a method. So we initialise
the class attribute once and for all at creation time and drop the instance
method.
That method is just returning self.node and is never overridden. We just use
the attribute directly instead and get rid of the method.
This is the beginning of series to simplify and unify verification of constraints
for actions.
I've caught multiple extensions in the wild lying about being
'internal', so it's time to move the goalposts on people. Goalpost
moving will continue until third party extensions stop trying to
defeat the system.
Inspired by how 'git rebase -i' works, we move the autoverb to the
commit line summary that it matches. We do this by iterating over all
rules and inserting each non-autoverb line into a key in an ordered
dictionary. If we find an autoverb line later, we then search for the
matching key and append it to the list (which is the value of each key
in the dictionary). If we can't find a previous line to move to, then we
leave the rule in the same spot.
Tests have been updated but the diff looks a little messy because we
need to change one of the summary lines so that it will actually move to
a new spot. On top of that, we added -q flags to future some of the
output and needed to change the file it modified so that it wouldn't
cause a conflict.
Now that the autoverb logic no longer acts on an individual rule line,
we don't need this parameter since we apply our logic just once at the
time of initialization.
This is needed for an upcoming change that will automatically rearrange the
rules based on the commit message. Before this patch, the autoverb logic only
applied to one rule at a time. This moves that logic one step up so that it can
iterate over all the rules and rearrange as needed.