Git

【Git基礎】git mergeとgit rebaseではコンフリクト時のHEAD側ブランチが逆

はじめに

Gitのmergeとrebaseの基本的なお話です

サンプル Git treeとコード

前提 Git tree

* <176d8be> (master) hello master
| * <f7edd2a> (HEAD -> feature) print feature
|/  
* <5e9878f> first commit

初期コミットからmasterブランチとfeatureブランチが枝分かれ

app.py(HEAD->feature)
def main():
    # main prints Hello feature
    print("Hello feature")

if __name__ == "__main__":
    main()
app.py(master)
def main():
    # main prints Hello master
    print("Hello master")

if __name__ == "__main__":
    main()

コンフリクト発生

HEADをfeatureブランチとしてmerge masterrebase masterそれぞれのコンフリクト状態を見る

git merge

git merge masterだとmasterがチャレンジャー

$ git checkout feature
$ git merge master

スクリーンショット 2018-01-15 22.16.07.png

HEAD(現在の変更)はずっとfeature

mergeコンフリクト解消後のGit tree

*   <07ad829>  (HEAD -> feature) merge master into feature
|\  
| * <176d8be>  (master) hello master
* | <f7edd2a>  print feature
|/  
* <5e9878f>  first commit

mergeでは既存のコミット達は消えない(破壊しない)

git rebase

git rebase masterだとfeatureがチャレンジャー

$ git checkout feature
$ git rebase master

スクリーンショット 2018-01-15 22.15.35.png

上スクショのようにrebase中はmasterがHEADとなる

rebaseコンフリクト解消後のGit tree

* <37f6e7e>  (HEAD -> feature) print feature
* <176d8be>  (master) hello master
* <5e9878f>  first commit

rebaseではかつてのコミット(f7edd2a)は消えmasterにそのまま乗る新しいコミットを作る

rebaseが完了するとHEADはfeatureに戻る

おわりに

  • ちなみに英語では現在の変更(HEAD)は ours 、入力側の変更(チャレンジャー)は theirs という

  • コンフリクト解消は本記事のスクショ用にも使ったVisual Studio Codeが便利