Share
Embed
2022-02-26開催 - merge / rebase 勉強会
Ueda Naoaki
November 14, 2023
Transcript
87 slides
-
本スライドについて Git のライセンスに準じ 以降のページは GNU General Public License v2.0 で公開しています。
https://choosealicense.com/licenses/gpl-2.0/ (C)Naoaki Ueda -
はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree
- フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 -
はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree
- フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 .git/objects/xx 配下のファイル -
はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree
- フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 git cat-file コマンドでオブジェクトの内 容を見ることができます -
はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree
- フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 ファイルパーミッション情報も保持 -
はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree
- フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 -
はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree
- フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 -
はじめに:diff と patch - diff コマンド :ファイル(ツリー)の差分を取る → patch ファイルを作成する
- patch コマンド:patch ファイルをファイル(ツリー)に適用する -
はじめに:diff と patch - diff コマンド :ファイル(ツリー)の差分を取る → patch ファイルを作成する
- patch コマンド:patch ファイルをファイル(ツリー)に適用する 一時期 kernel は tar でアーカイブされ patch ファイルで開発された -
はじめに:diff と patch - diff コマンド :ファイル(ツリー)の差分を取る → patch ファイルを作成する
- patch コマンド:patch ファイルをファイル(ツリー)に適用する 一時期 kernel は tar でアーカイブされ patch ファイルで開発された git は スナップショットの差分 を取る (tree と tree の diff を取る) -
main commit tree blob 凡例 git は スナップショットの差分 を取る (tree
と tree の diff を取る) C 0 C 1 T 1 T 0 B 1 B 0 -
main commit tree blob 凡例 git は スナップショットの差分 を取る (tree
と tree の diff を取る) 差分は patch として利用できる C 0 C 1 T 1 T 0 B 1 B 0 -
main commit tree blob 凡例 git は スナップショットの差分 を取る (tree
と tree の diff を取る) 差分は patch として利用できる git format-patch git am git cherry-pick git merge C 0 C 1 T 1 T 0 B 1 B 0 -
「チェックアウト中のブランチへ <commit> を統合する」 - コミットハッシュ - ブランチ - タグ -
refs git merge <commit> とは -
「チェックアウト中のブランチへ <commit> を統合する」 git merge <commit> とは - 歴史の統合 -
ブランチからコミットの履歴を辿れるようにする -
「チェックアウト中のブランチへ <commit> を統合する」 git merge <commit> とは - 歴史の統合 -
ブランチからコミットの履歴を辿れるようにする - 変更の統合 - ブランチへコミットに含まれる変更点を適用する -
non fast-foward なマージ main topic main topic merge で 新しいコミットを作る
git merge --no-ff topic -
「チェックアウト中のブランチへ <commit> を統合する」 git merge <commit> とは - 歴史の統合 -
ブランチからコミットの履歴を辿れるようにする - 変更の統合 - ブランチへコミットに含まれる変更点を適用する -
non fast-foward なマージによる「統合」の意味 main topic main topic main ブランチから topic
の歴史を辿れる git merge --no-ff topic -
non fast-foward なマージによる「統合」の意味 main topic main topic main ブランチから topic
の歴史を辿れる → 歴史の統合 git merge --no-ff topic -
non fast-foward なマージによる「統合」の意味 main topic main topic コミットを作るときに マージベースに各親コミットへのパッチ を適用する
git merge --no-ff topic -
non fast-foward なマージによる「統合」の意味 main topic main topic コミットを作るときに マージベースに各親コミットへのパッチ を適用する(3-way
merge) git merge --no-ff topic -
non fast-foward なマージによる「統合」の意味 main topic main topic コミットを作るときに マージベースに各親コミットへのパッチ を適用する(3-way
merge) → 変更の統合 git merge --no-ff topic -
non fast-foward なマージによる「統合」の意味 main topic main topic コミットを作るときに マージベースに各親コミットへのパッチ を適用する(3-way
merge) → 変更の統合 ※変更を取り込んだ ということ git merge --no-ff topic -
3-way merge をもう少し詳しく main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける C bas e C base = git merge-base main topic -
3-way merge をもう少し詳しく main topic git merge --no-ff topic C
bas e 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る C base = git merge-base main topic -
3-way merge をもう少し詳しく main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る C bas e C base = git merge-base main topic p main = git diff C base main p main -
3-way merge をもう少し詳しく C bas e main topic git merge
--no-ff topic 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic p main p topic -
3-way merge をもう少し詳しく C bas e main topic git merge
--no-ff topic C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic p main p topic 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる -
C bas e main topic git merge --no-ff topic C
base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic p main p topic ※tree 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる 3-way merge をもう少し詳しく -
C bas e main topic 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ
ベースからパッチを作る 3. マージベースの tree に各パッチを当てる git merge --no-ff topic C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} p main p topic T base 3-way merge をもう少し詳しく -
C bas e main topic 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ
ベースからパッチを作る 3. マージベースの tree に各パッチを当てる git merge --no-ff topic C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} p main p topic T base -
C bas e main topic git merge --no-ff topic p
main p topic T base 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} -
C bas e main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる p main p topic T merged T base C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} T merged = T base + p main + p topic -
C bas e main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる p main p topic T merged T base C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} T merged = T base + p main + p topic git checkout T base -- . git apply --index p main p topic git write-tree -
C bas e main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる p main p topic T merged T base C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} T merged = T base + p main + p topic git checkout T base -- . git apply --index p main p topic T merged = $(git write-tree) -
C bas e main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる 4. マージした各コミット を親コミットに、パッチを当 てた tree をルート tree にしたコミットを作る C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} T merged = T base + p main + p topic main = C merged ^1 topic = C merged ^2 p main p topic T merged T base C merged -
C bas e main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる 4. マージした各コミット を親コミットに、パッチを当 てた tree をルート tree にしたコミットを作る p main p topic T merged T base C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} T merged = T base + p main + p topic = C merged ^{tree} main = C merged ^1 topic = C merged ^2 C merged -
C bas e main topic git merge --no-ff topic 1.
マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る 3. マージベースの tree に各パッチを当てる 4. マージした各コミット を親コミットに、パッチを当 てた tree をルート tree にしたコミットを作る p main p topic T merged T base C base = git merge-base main topic p main = git diff C base main p topic = git diff C base topic T base = C base ^{tree} T merged = T base + p main + p topic = C merged ^{tree} main = C merged ^1 topic = C merged ^2 C merged git commit-tree -m “Merge branch ‘topic’” -p main -p topic T merged -
fast-forward(早送り) な merge main topic main topic git merge --ff
topic main は topic の歴史を辿れる -
fast-forward(早送り) な merge main topic main topic git merge --ff
topic main は topic の歴史を辿れる → topic の「歴史」を取り込んだ -
fast-forward(早送り) な merge main topic main topic git merge --ff
topic main は topic の歴史を辿れる → topic の「歴史」を取り込んだ main と topic の tree は同じ -
fast-forward(早送り) な merge main topic main topic git merge --ff
topic main は topic の歴史を辿れる → topic の「歴史」を取り込んだ main と topic の tree は同じ → topic の「変更」を取り込んだ -
git rebase ブランチの歴史を変えたい - fork 元(base)を変えたい - fork 元が古い →
fork した当時からの変更点がより多くなる → よりマージしにくくなる -
git rebase ブランチの歴史を変えたい - fork 元(base)を変えたい - fork 元が古い →
fork した当時からの変更点がより多くなる → よりマージしにくくなる - コミットをきれいにしたい -
git rebase ブランチの歴史を変えたい - fork 元(base)を変えたい - fork 元が古い →
fork した当時からの変更点がより多くなる → よりマージしにくくなる - コミットをきれいにしたい -
考え方 main topic main C 0 C 1 C 0
C 1 C’ 0 C’ 1 topic base を基点に同等のコミットを積み上げる -
C 0 main topic C 1 基点の base を見つける C
base C base = git merge-base main topic rebase 前 -
C 0 main topic C 1 topic ブランチ HEAD を
main と一致させる git checkout topic git reset --hard main main topic rebase 前 C base rebase 途中 -
C 0 C 1 main C base topic 積み上げるコミットのパッチを取り出す p
0 = git diff C base C 0 p 1 = git diff C 0 C 1 main topic rebase 前 rebase 途中 p 0 p 1 -
C 0 C 1 main C base topic パッチを使ってコミットを作る git
apply --index p 0 git commit main topic rebase 前 rebase 途中 p 0 p 1 C’ 0 -
C 0 C 1 main C base topic パッチを使ってコミットを作る main
topic rebase 前 rebase 後 p 0 p 1 C’ 0 C’ 1 git apply --index p 1 git commit -
C 0 C 1 main C base topic パッチを使ってコミットを作る =
cherry-pick main topic rebase 前 p 0 p 1 C’ 0 C’ 1 git apply --index p 1 git commit git apply --index p 0 git commit git cherry-pick C 0 git cherry-pick C 1 rebase 後 -
C 0 C 1 main C base topic パッチを使ってコミットを作る =
cherry-pick main topic rebase 前 p 0 p 1 C’ 0 C’ 1 git apply --index p 1 git commit git apply --index p 0 git commit git cherry-pick C 0 git cherry-pick C 1 rebase は reset と cherry-pick を駆使している rebase 後 -
C 0 C 1 main C base topic パッチを使ってコミットを作る =
cherry-pick main topic rebase 前 p 0 p 1 C’ 0 C’ 1 git apply --index p 1 git commit git apply --index p 0 git commit git cherry-pick C 0 git cherry-pick C 1 rebase は reset と cherry-pick を駆使している 編集可能にしたのが git rebase --interactive rebase 後 -
C 0 C 1 main C base topic パッチを使ってコミットを作る =
cherry-pick main topic rebase 前 p 0 p 1 C’ 0 C’ 1 git apply --index p 1 git commit git apply --index p 0 git commit git cherry-pick C 0 git cherry-pick C 1 rebase は reset と cherry-pick を駆使している 編集可能にしたのが git rebase --interactive rebase 後 -
C 0 C 1 main C base topic パッチを使ってコミットを作る =
cherry-pick main topic rebase 前 p 0 p 1 C’ 0 C’ 1 git apply --index p 1 git commit git apply --index p 0 git commit git cherry-pick C 0 git cherry-pick C 1 rebase は reset と cherry-pick を駆使している 編集可能にしたのが git rebase --interactive rebase 後