藤原です。
2016年10月28日 16:34 ohira <
shin....@gmail.com>:
> おおひらです。
>
> hg コマンドの複数の処理をまとめてロールバックする方法はありませんでしょうか?
>
> SQLのDBMSのトランザクションのようなことがやりたいのです。
>
https://www.postgresql.jp/document/7.2/tutorial/tutorial-transactions.html
>
> =====
>
> どうして、そんなことがやりたいのかというと
>
> hg のコマンドであれば hg rollback が使えるけど、
> hg flow では一回のhg flow コマンドで複数の処理とcommitが行われるので
> hg rollbakc で戻せるのは最後のものだけで中途半端になってしまいます。
>
> hg strip <番号>で hg flow で処理した部分の最初を指定すれば目的を
> 達成できると思うのですが
> hgのコマンドで処理して、hg rollback の場合は<番号>の指定が不要で、
> 間違った番号を指定するリスクが少ないという意見がありまして。
一度の hg flow 実行に起因する複数の内部的 commit の成果を、hg
rollback で一括破棄すること自体は可能です。
※ 以下、動作確認等無しで書いてますので、細部の間違いには目をつぶっ
てください(笑)
例えば、以下のような感じで、flow コマンド処理自体を、transaction
スコープとして囲むラッパー処理を用意しておいて:
def flowwrap(orig, ui, repo, cmd=None, *arg, **kwarg):
with repo.transaction('flow'):
return orig(ui, repo, cmd, *arg, **kwargs)
hgflow エクステンションの cmdtable 中の "flow" エントリの関数を、
上記のラッパーでラップしてやります。
from mercurial import error, extensions
def extsetup(ui):
try:
flowmod = extensions.find('hgflow')
extensions.wrapcommand(flowmod.cmdtable 'flow', flowwrap)
except KeyError:
raise error.Abort('hgflow is not enabled!')
以上の処理を自前のエクステンションにおいて実施することで、
"hg flow" コマンド処理全体がトランザクション対象になります。
但し、hg flow コマンド全体がトランザクション対象となることで、コマ
ンドの終了は、以下の2つに明確に分類されます。
- 成功: すべてのコミット成果の記録
- 失敗: すべてのコミット成果の破棄
例えば、マージ処理で衝突が発生した場合、 hgflow は例外終了するため、
途中までの成果が全て破棄されてしまいます。
現状の hgflow は、merge を tag や commit といった他の処理と同列に
扱っていて、エラー復帰の場合は問答無用で例外終了、という定型的な流
れなのですが、update 処理みたいな特別扱いにした上で:
https://bitbucket.org/yujiewu/hgflow/src/eef72dda34c5baffa4a629123bbafc3904a8c6a4/src/hgflow.py?#hgflow.py-1079
衝突検出時には識別可能な例外を raise するようにすれば、同梱エクス
テンションの shelve での対処と同じ要領で、途中成果を残したままにで
きるんですけどねぇ。
https://www.mercurial-scm.org/repo/hg/file/438173c41587/hgext/shelve.py#l769
とは言え、現状の hgflow の実装は、finish 等による上流へのマージの
前に、予め feature ブランチ側で衝突解消済みと仮定しているみたいで
すから、そもそもこの辺の心配は無用なのかな?
と思ったら、再開機能の要望が issue であがってますね。
https://bitbucket.org/yujiewu/hgflow/issues/53/resume-running-scenario-after-error
なお、Mercurial はコマンド実行横断のトランザクションはサポートして
いません。ですので、仮に再開機能が実装されたとしても、衝突解消を含
んだ一連の操作を rollback の機能で一括破棄することはできません。
この場合は strip の利用が必須になります。
また、先述したラッパー関数を使用する場合、flow の pull アクション
が作業領域更新段階で失敗した時も、履歴情報取り込み成果が破棄されて
しまいます。
余計な通信の抑止を考えた場合、アクションに応じてトランザクション適
用を切り替えた方が妥当でしょうね。
finish, promote あたりに適用すれば十分かな?
> (hg rollback にしてもまとめてhg strip にしてもローカルPCのリポジトリでドラフト状態の話なので
> 多少多めに hg strip して hg pull すれば問題ないように思えるのですが、間違っていますでしょうか)
>
> hg flow rollback とか有ったら便利そうなのですが。。。
--
----------------------------------------------------------------------
FUJIWARA Katsunori(
flying...@gmail.com)