Git/マージ作業

基本

merge後メインとなるブランチに居る状態でmergeしたいブランチを指定する。

$ git checkout hoge
$ git merge piyo

このへんの指定の仕方は rebase と逆(rebase では 繋ぎ変えたいブランチにいる状態で繋ぎたいブランチを指定する)。

マージに使うツールの登録

$ git config --global merge.tool "meld"

衝突

merge, pull などの作業で同じ親をもつファイルの編集箇所が被ると衝突したと感知される。

この時点で、ファイルにはあのおなじみのマーカーが挿入されてユーザーに解決を迫ることになる。 つまりこの時点でソースコード的には(マーカーが挿入されたことで)ぶっ壊れてしまっている

衝突の解決

$ git status

で衝突したファイルはわかるので、マーカーの入っている部分を意図したとおりになるように修正(マーカーは当然取り除く)し、保存。

ここでこのファイルを再びステージングするとマージ完了とみなされる

マージツールを登録している場合は

$ git mergetool

でマージ準備状態でマージツールが起動するので意図したように合わせて編集して保存する。 この場合はツールを終了させると自動的にステージングまで完了してくれる

マージ操作そのものをなかったコトにする

思った以上にマージが複雑で仕切り直ししたい時がある。しかしもう衝突してマーカーが入りまくっている・・・もう辞めたい。という時に

$ git reset --hard ORIG_HEAD

で操作そのものがなかったことになる。

ブランチがマージ済か確認する

リポジトリを作成する

$ git init

とりあえずファイル作ってコミット

$ touch index.html
$ git add index.html
$ git commit -m "Init"

いくつかコミットを重ねて master ブランチが伸びる

b1ブランチを作る

$ git checkout -b b1

この時点で

$ git branch
*b1
 master

である

master に戻る

$ git checkout master

マージ済ブランチを確認する

$ git branch --merged
  b1
* master

現時点では b1 は master と一致しているのでマージ済と判断されているのか?

b1を伸ばして再び master に戻り

$ git branch --merged
* master

b1 がマージ済では無くなった

これはカレントのブランチに対してマージ済のブランチを示している。

git branch --no-merged
  b1

となる。

では b1 側から見るとどうなる? b1 に移動する

$ git branch --merged
* b1
  master

こうなる。 b1 は master から派生して、master はまだ派生したタイミングから伸びてないのでマージ済と判断されている。

では master を伸ばしてみる

$ git branch --merged
* b1

こうなる。

では master に b1 をマージする

$ git checkout master
$ git merge b1
$ git branch --merged
 b1
*master

OK

マージ後のブランチはどうなる?

master に対してhogeブランチの変更をマージした場合 master は本線とみなしているので継続なのはわかるが、 hoge ブランチはどうなるのか?

結果として hoge ブランチは無くならない。 hoge ブランチの先頭は、マージコミットが発生しているならそのマージコミットの直前の hoge ブランチで入れた最終変更のリビジョンとなる。ff の場合連結された先頭のリビジョンになる。

この状態がよくあるのは、本番リリースの master ブランチと開発本線の develop ブランチの関係である。 開発が終了して本番リリースのために master にマージするが、開発は開発で先に進むというやつ。

逆に開発を分けるためだけに単に作られたトピックブランチのようなモノはマージすると継続しない。 ここで消すことになる。

ブランチを消すということは歴史を消すわけでなく、積み上げたリビジョン構造に対するラベルを取り外すということなので、変更の記録がなくなるわけではない。単にその名前でハンドリングできなくなるだけ。

vcs/git/merge_ope.txt · 最終更新: 2019-04-04 18:11 by ore