勉強日記

チラ裏

Version Control with Git ch9 Merges (3/3)

shop.oreilly.com


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とは、存在しなかった歴史をでっち上げる行為
    • 誰もそのようなファイル作ってない
    • 誰もそのファイルが正常に動いていたと確信を持っては言えない