Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2022-02-26開催 - merge / rebase 勉強会

Ueda Naoaki
November 14, 2023

2022-02-26開催 - merge / rebase 勉強会

Ueda Naoaki

November 14, 2023
Tweet

More Decks by Ueda Naoaki

Other Decks in Programming

Transcript

  1. はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree

    - フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持
  2. はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree

    - フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 .git/objects/xx 配下のファイル
  3. はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree

    - フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 git cat-file コマンドでオブジェクトの内 容を見ることができます
  4. はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree

    - フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持 ファイルパーミッション情報も保持
  5. はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree

    - フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持
  6. はじめに:Git の 3 つのオブジェクト - blob - ファイルの実体 - tree

    - フォルダ階層を保持 - commit - コミット情報の保持 - ルート tree と 1 つ前の commit 参照を保持
  7. はじめに:diff と patch - diff コマンド :ファイル(ツリー)の差分を取る → patch ファイルを作成する

    - patch コマンド:patch ファイルをファイル(ツリー)に適用する 一時期 kernel は tar でアーカイブされ patch ファイルで開発された
  8. はじめに:diff と patch - diff コマンド :ファイル(ツリー)の差分を取る → patch ファイルを作成する

    - patch コマンド:patch ファイルをファイル(ツリー)に適用する 一時期 kernel は tar でアーカイブされ patch ファイルで開発された git は スナップショットの差分 を取る (tree と tree の diff を取る)
  9. main commit tree blob 凡例 git は スナップショットの差分 を取る (tree

    と tree の diff を取る) 差分は patch として利用できる C 0 C 1 T 1 T 0 B 1 B 0
  10. 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
  11. 「チェックアウト中のブランチへ <commit> を統合する」 git merge <commit> とは - 歴史の統合 -

    ブランチからコミットの履歴を辿れるようにする - 変更の統合 - ブランチへコミットに含まれる変更点を適用する
  12. 「チェックアウト中のブランチへ <commit> を統合する」 git merge <commit> とは - 歴史の統合 -

    ブランチからコミットの履歴を辿れるようにする - 変更の統合 - ブランチへコミットに含まれる変更点を適用する
  13. 3-way merge をもう少し詳しく main topic git merge --no-ff topic 1.

    マージベース(共通祖先)を見つける C bas e C base = git merge-base main topic
  14. 3-way merge をもう少し詳しく main topic git merge --no-ff topic C

    bas e 1. マージベース(共通祖先)を見つける 2. マージする各コミット に対し、それぞれマージ ベースからパッチを作る C base = git merge-base main topic
  15. 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
  16. 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
  17. 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 に各パッチを当てる
  18. 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 をもう少し詳しく
  19. 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 をもう少し詳しく
  20. 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
  21. 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}
  22. 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
  23. 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
  24. 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)
  25. 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
  26. 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
  27. 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
  28. fast-forward(早送り) な merge main topic main topic git merge --ff

    topic main は topic の歴史を辿れる → topic の「歴史」を取り込んだ
  29. fast-forward(早送り) な merge main topic main topic git merge --ff

    topic main は topic の歴史を辿れる → topic の「歴史」を取り込んだ main と topic の tree は同じ
  30. fast-forward(早送り) な merge main topic main topic git merge --ff

    topic main は topic の歴史を辿れる → topic の「歴史」を取り込んだ main と topic の tree は同じ → topic の「変更」を取り込んだ
  31. git rebase ブランチの歴史を変えたい - fork 元(base)を変えたい - fork 元が古い →

    fork した当時からの変更点がより多くなる → よりマージしにくくなる
  32. git rebase ブランチの歴史を変えたい - fork 元(base)を変えたい - fork 元が古い →

    fork した当時からの変更点がより多くなる → よりマージしにくくなる - コミットをきれいにしたい
  33. git rebase ブランチの歴史を変えたい - fork 元(base)を変えたい - fork 元が古い →

    fork した当時からの変更点がより多くなる → よりマージしにくくなる - コミットをきれいにしたい
  34. 考え方 main topic main C 0 C 1 C 0

    C 1 C’ 0 C’ 1 topic base を基点に同等のコミットを積み上げる
  35. C 0 main topic C 1 基点の base を見つける C

    base C base = git merge-base main topic rebase 前
  36. C 0 main topic C 1 topic ブランチ HEAD を

    main と一致させる git checkout topic git reset --hard main main topic rebase 前 C base rebase 途中
  37. 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
  38. 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
  39. 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
  40. 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 後
  41. 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 後
  42. 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 後
  43. 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 後
  44. 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 後