Siddharth Agarwal <sid0@fb.com> [Wed, 07 Oct 2015 22:58:52 -0700] rev 26528
filemerge: move 'merging' output to before file creation
This has no visible impact but makes some future work simpler.
Siddharth Agarwal <sid0@fb.com> [Wed, 07 Oct 2015 21:21:56 -0700] rev 26527
filemerge.filemerge: make a tuple containing merge paths on disk
We're going to need this same tuple elsewhere.
Siddharth Agarwal <sid0@fb.com> [Wed, 07 Oct 2015 16:14:57 -0700] rev 26526
filemerge: switch trymerge boolean to mergetype enum
trymerge = False becomes mergetype = nomerge, and trymerge = True becomes
mergetype = fullmerge or mergeonly, depending on whether a premerge happens.
Siddharth Agarwal <sid0@fb.com> [Wed, 07 Oct 2015 15:13:41 -0700] rev 26525
filemerge: add some merge types
We're going to turn the 'trymerge' boolean into a 'mergetype' enum with these
three possible values.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Thu, 08 Oct 2015 01:41:30 +0900] rev 26524
shelve: restore unshelved dirstate explicitly after aborting transaction
Before this patch, "hg unshelve" uses aborting a current transaction
to discard temporary changes while unshelving.
This assumes that dirstate changes in a transaction scope are kept
even after aborting it. But this assumption will be broken by
"transactional dirstate". See the wiki page below for detail about it.
https://mercurial.selenic.com/wiki/DirstateTransactionPlan
This patch explicitly saves shelved dirstate just before aborting
current transaction, and restore dirstate with it after aborting by
utility function '_aborttransaction()' added by previous patch.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Thu, 08 Oct 2015 01:41:30 +0900] rev 26523
shelve: restore shelved dirstate explicitly after aborting transaction
Before this patch, "hg shelve" uses aborting a current transaction to
discard temporary changes while shelving.
This assumes that dirstate changes in a transaction scope are kept
even after aborting it. But this assumption will be broken by
"transactional dirstate". See the wiki page below for detail about it.
https://mercurial.selenic.com/wiki/DirstateTransactionPlan
This patch explicitly saves shelved dirstate just before aborting
current transaction, and restore dirstate with it after aborting by
utility function '_aborttransaction()' added by previous patch.
This patch replaces 'if tr: tr.abort()' by 'lockmod.release(tr)',
because the former is already done in '_aborttransaction()' (and the
latter has no effect), if current transaction is aborted in it
successfully. Otherwise, the latter is enough to trigger aborting.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Thu, 08 Oct 2015 01:41:30 +0900] rev 26522
shelve: add utility to abort current transaction but keep dirstate
"hg shelve" and "hg unshelve" use aborting a current transaction to
discard temporary changes while (un)shelving.
This assumes that dirstate changes in a transaction scope are kept
even after aborting it. But this assumption will be broken by
"transactional dirstate". See the wiki page below for detail about it.
https://mercurial.selenic.com/wiki/DirstateTransactionPlan
This patch adds utility function "_aborttransaction()" to abort
current transaction but keep dirstate changes for (un)shelving.
'dirstate.invalidate()' just after aborting a transaction should be
removed soon by subsequent patch, which writes or discards in-memory
dirstate changes at releasing transaction according to the result of
it.
BTW, there are some other ways below, which (seem to, at first glance)
resolve this issue. But this patch chose straightforward way for ease
of review and future refactorring.
- commit transaction at first, and then rollback it
It causes unintentional "dirty read" of running transaction to
other processes at committing it.
- use dirstateguard to save and restore shelved dirstate
After DirstateTransactionPlan, making 'dirstate.write()' write
in-memory changes into actual file requires
'transaction.writepending()' while transaction running.
It causes meaningless writing other in-memory changes out, even
though they are never referred.
In addition to it, it isn't desirable that scope of dirstateguard
and transaction intersects each other.
- get list of files changed from the parent, keep it in memory, and
emulate that changes after aborting transaction
This additional memory consumption may block aborting transaction
in large repository (on small resource environment).
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Thu, 08 Oct 2015 01:41:30 +0900] rev 26521
dirstate: split write to write changes into files other than .hg/dirstate
'_writedirstate()' is used mainly for "transactional dirstate". See
the wiki page below for detail about it.
https://mercurial.selenic.com/wiki/DirstateTransactionPlan
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Thu, 08 Oct 2015 01:41:30 +0900] rev 26520
bookmarks: use recordchange instead of writing if transaction is active
Before this patch, 'bmstore.write()' always write in-memory bookmark
changes into '.hg/bookmarks' regardless of transaction activity.
If 'bmstore.write()' is invoked inside a transaction and it writes
changes into '.hg/bookmarks', then:
- original bookmarks aren't restored at failure of that transaction
This breaks "all or nothing" policy of the transaction.
BTW, "hg rollback" can restore bookmarks successfully even before
this patch, because original bookmarks are saved into
'.hg/journal.bookmarks' at the beginning of the transaction, and
it (actually renamed as '.hg/undo.bookmarks') is used by "hg
rollback".
- uncommitted bookmark changes are visible to other processes
This is a kind of "dirty read"
For example, 'rebase.rebase()' implies 'bmstore.write()', and it may
be executed inside the transaction of "hg unshelve". Then, intentional
aborting at the end of "hg unshelve" transaction doesn't restore
original bookmarks (this is obviously a bug).
This patch uses 'bmstore.recordchange()' instead of actual writing by
'bmstore._writerepo()', if any transaction is active
This patch also removes meaningless restoring bmstore explicitly at
the end of "hg shelve".
This patch doesn't choose fixing each 'bmstore.write()' callers as
like below, because writing similar code here and there is very
redundant.
before:
bmstore.write()
after:
tr = repo.currenttransaction()
if tr:
bmstore.recordchange(tr)
else:
bmstore.write()
Even though 'bmstore.write()' itself may have to be discarded by
putting bookmark operations into transaction scope, this patch chose
fixing it to implement "transactional dirstate" at first.
Siddharth Agarwal <sid0@fb.com> [Wed, 07 Oct 2015 00:27:23 -0700] rev 26519
filemerge: run symlink check for :merge3
Just like :merge, :merge3 doesn't support merging symlinks.