(VSCodeのために) MercurialよりGitのほうがマージしやすい問題を解消する
Live With Linux::software
- TOP
- Articles
- Live With Linux
- (VSCodeのために) MercurialよりGitのほうがマージしやすい問題を解消する
マージとthree-way merge
まず、我々Mercurialユーザーはひとつの事実を受け入れなければならない。
それは、「世の中ではGitのほうが使われている」という事実だ。
Gitのほうが使われているということは、Gitのほうが有力なツールが多く揃い、Gitのほうが使いやすい世の中になっているということを意味する。
その問題のひとつにマージがある。
この「マージ」という概念が、GitとMercurialでは大きく違う。
Gitではそもそもワーキングツリーを持つリポジトリに対するpushというのができないようになっている。 また、ワーキングツリー上でpullした場合、conflictするならばpullに失敗するという仕様だ。
Mercurialはそもそもワーキングツリーを持たないリポジトリというものがなく、pull操作は基本的に妨げられることがない
(push操作はremoteのHEADが進んでいる場合はpullしてからでないとpushできない)。
Gitと違いこの操作によってワーキングツリーが変更されるということはなく、ワーキングツリーの更新にはupdate
を行う必要がある。
このときconflictが発生するなら自動的に(強制的に)mergeを行うことになる。
また、既に変更がcommitされており、remoteにないcommitによってconflictが発生する場合、
Mercurialでは複数のHEADを持つ状態になる 。
複数のHEADをひとつにまとめるのがmerge
である。これはGitでも見られるマージ操作だ。
Gitの場合は競合したファイルにマークをつけた状態になる。 一方、Mercurialではマージツールがある場合はThreeWayMergeというのが行われる。
MercurialのThreeWayMergeは専用のソフトウェアを使って行う高度な競合解消作業だ。
「普通はマージツールなんてないから」と思うかもしれないが、Vimにはvimdiff
というものが含まれているため、Vimがあるだけでマージツールを利用したThreeWayMergeになる。
また、KDEコンポーネントのkdiff3も使えたりする。
Vimdiffがマージツールとして使いやすいかというと、「慣れによる」というのが私の回答である。 個人的にはMeldのほうが直感的で使いやすいと思うし、Vimdiffを使うのならMeldをインストールしてマージするというのも考えて良いと思う。
なお、意図せずconflictが発生してしまい、マージツールがない場合は、hg rollback
によって競合を発生させたremoteのリビジョンを外しておき、もう一度pullし直すという方法がとれる。
Git-styleでマージしたい
もちろん、何の機能もないエディタを使ってマークをつけられただけのファイルを編集するのは大変である。
だが、Gitユーザーが多いという事実は、それをそのまま放置するようなことはない、ということを意味している。 つまり、VSCodeのマージ機能が便利過ぎるのだ。
さすがにこれはMeldよりも使いやすい。
じゃあMercurialでもVSCodeでマージしたいんじゃ! と思ったときにその情報がない。 というか、今Googleで検索すると、関連情報にすらたどり着けない。
というわけで書いたのが今回の記事だ。
マージの際に何を使うか、というのはマージツールの設定として決めることができる。
これは、.hgrc
の[merge-tools]
セクションである。
現在どのようなマージツールが定義されているかは、hg config merge-tools
で知ることができる。
ちなみに、Vimdiffのpriorityが -10
, Gvimdiffが
-9
なのに対し、Meldはpriorityの設定がないのでMeldがあればMeldが使われる。
そもそもどうやってマージするか、ということについては、
[ui]
セクションの merge
という項目にある。
この詳細はhg help merge-tools
で見ることができる。
さて、Mercurialでは同一のファイルが変更された場合、問答無用で競合状態にする。 機械的に統合できる場合でも勝手に統合したりはしない。
Gitの場合、変更箇所が競合している場合にだけ手動での解決を要求する。そうでなければ同一ファイルに対する変更を取り込む。
:merge
はGitと同様の挙動になる。解決できない競合マークがつけられる。
場合によっては :other
や :local
も便利なオプションである。
finally, GitみたいにマージしてVSCodeでいい感じに競合解消したい場合、
.hgrc
に次のように書けば良い。
[ui]
merge = :merge