The 'start' variable pointed to qtip in self.series, but it was used for
indexing self.fullseries.
When fullseries had holes and the patch was moved to self.fullseries[start]
it would end up too early in self.series and it could thus not be
found in self.series[start:] and it would crash.
Now the 'fullstart' index in fullseries is found used instead.
In secret mode qfinished changeset were move to the draft phase in all case[1]
without regard to phases.new-commit value
This changeset ensure qfinish does not automatically promote a changeset
further than the phases.new-commit value.
Note: This may also result in qfinished changeset made public if
phases.new-commit is set to public.
[1] "In all case" where parent have a compatible phase. Qfinish keep never
altering phases of changeset not involved in the qfinish.
-n could be confused for --dry-run by foolhardy users, resulting in
permanent data loss.
As leaving a backup when none was requested is significantly less
disastrous, the short option is silently ignored. Old scripts continue
to work, users only get lightly burned.
Originally, mq.strip called repair.strip a single rev at a time.
repair.strip stores in a backup bundle any revision greater than
the revision being stripped, strips, then restores the backup with
repo.addchangegroup. So, when stripping revisions on more than one
topological branch, some could end up being restored from the backup
bundle, only to be later removed by a subsequent repair.strip call.
But repo.addchangegroup calls hooks for all those restore operations.
And 1671d21e8e41 changed it to delay all hook calls until the
repository lock were released - by mq.strip, after stripping all
revisions. Thus, the hooks could be called over revisions already
removed from the repository at that point.
By generating the revision lists at once inside repo.strip, we avoid
calling addchangegroup for temporary restores. Incidentally, this
also avoids creating many backup files for a single strip command.
Since c06eb45e85a7, mq saves the nodeid of the first applied patch to
cache/branchheads, which breaks the optimized cache handling introduced in
1808e27e1362. The problem is the revision being committed is appended to
mqrepo.applied after the commit succeeds, which means mqrepo._branchtags()
performs a regular update and write the first applied patch to the branch
cache.
One solution is to set a context variable _committingpatch on the mqrepo while
it is committing a patch and to take it in account when deciding to fast-path
mqrepo._branchtags(). Not really elegant but it works.
The changes to test-mq-caches.t reverse changes introduced by c06eb45e85a7. The
cache should not have been updated with mq records.
The changes to test-keyword.t are indirectly caused by c06eb45e85a7.
Reported and analyzed by Yuya Nishihara <yuya@tcha.org>
Notes:
- qpush still makes a slow path _branchtags() call when checking heads. Maybe
this can be optimized.
- be careful when merging this patch in default as secretcommit() was renamed
newcommit() right after the end of the code freeze.
The current behaviour is to return the previous one in the series but at the
same time the implementation is buggy because it does not take guarded patches
in account.
This was breaking my remotebranches extension in a completely
mystifying way, because repo.lookup was failing to resolve the
statusentry. I'm not sure how this works absent my remotebranches
extension, but doing it this way looks more correct and doesn't break
anything.
When mq changeset are secret, they don't appear in outgoing and won't be
pushed. So it's not necessary to abort the push.
The checkpush call is protected by lock to prevent race on phase.
As mq automatically sets changesets as secret, it should make them draft when he
is done with it. We do not move them automatically to draft when we detect that
something else have also set them as secret through their parents.
Before the code optimistically relied on savedirty not being called a cancelled
transaction. If it was called it could save incorrect data.
Instead we now start using the invalidate method introduced in 469ecb6e5f24.
It wasn't obvious from the code how qsave mocked around with .hg/patches and
.hg/patches.? and what was going on.
This makes it more explicit so it will survive future refactorings.
When renaming a patch A as B where B was previously qfolded into A and
therefore marked as removed, a versioned MQ would first restore B before
marking it as a copy of A, thus losing A changes. The undelete() call is
probably a left-over, wctx.copy() explicitely handles the case where the
destination is removed.
Also note that status command represents "hg rm b; hg mv a b" as:
A b
a
R a
which explains the first hunk in test-mq-qrename.t.