Version Control with Git ch9 Merges (3/3)
Merges(続き)
Applying Merge Startegies
- Gitの自動選択
- up-to-date / fast-forward
- 可能な限り単純で低コストなマージ戦略を検討する
- octopus merge
- other_branchを2つ以上選択したらこれ
- 一度に3ブランチ以上マージする戦略は他にない
- other_branchを2つ以上選択したらこれ
- resolve
- 上記に該当しない場合、かつてはこれがGitデフォルトだった
- ~2005
- 今はそうでないので、明示的に指定する必要あり
git merge -s resolve Bob
- 上記に該当しない場合、かつてはこれがGitデフォルトだった
- recursive
- 2005~デフォルト
- contributed by Fredrik Kuivinen
- resolveより優れる点
- 汎用的
- コンフリクト少ない
- 欠点がない
- リネームをうまく扱える
- 2005~デフォルト
- up-to-date / fast-forward
コラム: Using ours and subtree
- その昔、gitweb.gitプロジェクトがあった
- 今はgit.gitプロジェクトのサブセット
- 同じことをするには:
- gitweb.gitプロジェクトをgit.gitプロジェクトのgitwebサブディレクトリにまるっとコピー
- git.gitプロジェクトを通常通りコミット
- すでに最新をコピー済なので
ours
でマージgit pull -s ours gitweb.git master
- 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とは、存在しなかった歴史をでっち上げる行為
- 誰もそのようなファイル作ってない
- 誰もそのファイルが正常に動いていたと確信を持っては言えない