Version Control with Git ch9 Merges (3/3)

Git勉強メモ

出典: 


Merges(続き)

Applying Merge Startegies

  • Gitの自動選択

    1. up-to-date / fast-forward

      • 可能な限り単純で低コストなマージ戦略を検討する
    2. octopus merge

      • other_branchを2つ以上選択したらこれ

        • 一度に3ブランチ以上マージする戦略は他にない
    3. resolve

      • 上記に該当しない場合、かつてはこれがGitデフォルトだった

        • ~2005
      • 今はそうでないので、明示的に指定する必要あり
      • git merge -s resolve Bob
    4. recursive

      • 2005~デフォルト

        • contributed by Fredrik Kuivinen
      • resolveより優れる点

        • 汎用的
        • コンフリクト少ない
        • 欠点がない
        • リネームをうまく扱える

コラム: Using ours and subtree

  • その昔、gitweb.gitプロジェクトがあった
  • 今はgit.gitプロジェクトのサブセット
  • 同じことをするには:

    1. gitweb.gitプロジェクトをgit.gitプロジェクトのgitwebサブディレクトリにまるっとコピー
    2. git.gitプロジェクトを通常通りコミット
    3. すでに最新をコピー済なのでoursでマージ

      • git pull -s ours gitweb.git master
    4. gitweb.gitの最新の変更をgit.gitに取り込みたくなったら

      • git pull -s subtree gitweb.git master

Merge Drivers

  • text merge driver, binary merge driver, union merge driver などがある
  • .gitattributeでファイルタイプとドライバの紐付けを行うことができる
  • custom merge driverを自作する場合は、custom diff driverのことも調べよう
  • 【補】xlsxをgit diffできるやつ

    • これはまさしくxlsx diff driver

How Git Thinks About Merges

Merges and Git’s Object Model

  • ほとんどのVCS: 「ブランチAをブランチBにマージする」のと「ブランチBをブランチAにマージする」のとは異なる

    • commitが前commitからの「変更差分」を保存するため
  • Git: 新しいcommitがcurrentブランチのHEADに追加されるが、commitやtreeの作成自体は対称

    • commitが、前commitからの差分ではなく、tree = その時点での全ファイルを指しているため

Squash Merges

  • 歴史を改変するので気をつけようね
  • 歴史が複雑なのは良し悪し

    • git blameやgit bisectは細かくcommitが分かれていてこそ

Why Not Just Merge Each Change One by One?

  • デフォルトでrebaseのような挙動でない理由
  • rebaseとは、存在しなかった歴史をでっち上げる行為

    • 誰もそのようなファイル作ってない
    • 誰もそのファイルが正常に動いていたと確信を持っては言えない