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

ブランチ操作 / 02-a-branch

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

ブランチ操作 / 02-a-branch

Avatar for kaityo256

kaityo256 PRO

March 02, 2026
Tweet

More Decks by kaityo256

Other Decks in Education

Transcript

  1. 4 44 なぜブランチを分けるか Alice Bob 中央 リポジトリ 1. クローン 2.

    機能A1を実装 3. プッシュ 4. クローン 5. 機能A1を無効化して機能B追加 5. プッシュ 6. 機能A2を実装 競合
  2. 5 44 なぜブランチを分けるか 何が問題だったか? Aliceが機能A1を実装した状態という「中途半端な状態」をコミットした Bobはその状態をクローン、動作しないのでA1を無効化せざるを得なかった どうすれば良い? 案1: 「中途半端な状態をコミットしてはならぬ」というルールを作る 案2:

    ブランチを作成して自由にコミットするが、マージの時にルールを作る https://www.youtube.com/watch?v=4XpnKHJAok8 Tech Talk: Linus Torvals on git ワークフロー(Work Flow)の導入 以下の動画で、Linusが「コミットルール」について触れている
  3. 10 44 個人開発とワークフロー main feature_A feature_B ここでバグ発覚 機能Aを途中 まで開発 機能A完成

    機能Bを途中 まで開発 機能B完成 もし「機能ごとにブランチを派生させる」ルールを守っていたら?
  4. 12 44 ワークフローのまとめ なぜブランチを分けるか • いま行っている作業は何かを明確にするため • 複数の作業を同時に行わない • Gitは便利ツールではなく「作業フロー」を

    実現するのを助けてくれるツール • 「作業フロー」を変えなければ意味は薄い ワークフローとは何か • 多人数開発時のブランチ運用のルール • 個人開発でも有用 • 基本は「mainでコミットしない」こと • ブランチで開発、mainにマージ
  5. 13 44 カレントブランチとコミット Gitの歴史:コミットがつながったもの ブランチ:コミットについたラベル カレントブランチ:HEADが指しているブランチ branch HEAD branch HEAD

    other other コミットするとコミットが作られカレントブランチが指していたコミットにつながる さらにカレントブランチが新たに作られたコミットを指す 他のブランチは動かない ブランチを切り替えてコミットすると歴史が分岐する
  6. 14 44 コミットと差分 コミットは「自分の親コミット」を知っている 親コミットをたどることで歴史をたどることができる コミット1 コミット2 コミット1 コミット2 +

    = パッチ コミット1からコミット2が作られた コミットはそれぞれの時点でのスナップショット表す コミット間の線は差分(パッチ)を表す
  7. 15 44 ブランチ作成と切り替え ブランチの作成 $ git branch ブランチ名 ブランチをつけたいコミット 「コミット」を省略すると、カレントブランチが指すコミットに別名をつける

    $ git branch ブランチ名 ブランチの切り替え $ git switch ブランチ名 ブランチを作成して切り替える $ git switch –c ブランチ名
  8. 16 44 ブランチ作成と切り替え main HEAD main HEAD newbranch main newbranch

    HEAD $ git branch newbranch $ git switch newbranch $ git switch -c newbranch
  9. 17 44 マージ 「カレントブランチ」に「ブランチ名」の修正を取り込む $ git merge ブランチ名 個人開発の場合、mainであることがほとんど $

    git merge ブランチ名を省略すると「上流ブランチ」をマージ(後述) マージとは、二つのブランチの共通祖先を見つけ、そこから の修正を全て取り込んだ新たなコミットを作る作業
  10. 18 44 Fast-Forward マージ main feature + + + =

    main feature $ git merge feature HEAD HEAD カレントブランチがマージしたいブランチの直接の祖先であるとき カレントブランチを 移動するだけでマージ完了
  11. 19 44 Non-fast forward マージ main feature HEAD main feature

    HEAD $ git merge feature 新に作られたコミットを マージコミットと呼ぶ
  12. 20 44 マージコミット main branch HEAD + + = =

    non fast-forwardマージで作られるコミット 親コミットを二つ持つ 二つの線は、それぞれの親からの差分を表している
  13. 21 44 マージコミット main feature HEAD main feature HEAD +

    $ git merge --no-ff feature Fast-forwardマージ可能な場合でもマージコミットを作ることができる
  14. 22 44 マージコミット main feature HEAD マージコミットを作ると、機能追加をしようとした ブランチがどこから分岐したかの情報が残る main feature

    HEAD fast-forwardすると歴史が一本になって見やすい どこから分岐したかの情報が失われ、マージを取り消しづらい
  15. 23 44 ブランチの削除 $ git branch -d ブランチ名 指定したブランチを削除する 削除されるのはブランチだけで、コミットは消えない

    main feature HEAD $ git branch –d feature Deleted branch feature (was 1c168e1). main HEAD 1c168e1 削除前に指していたコミットハッシュが表示される
  16. 24 44 ブランチの削除 main HEAD feature $ git branch -d

    branch error: The branch 'feature' is not fully merged. If you are sure you want to delete it, run 'git branch -D feature'. マージされていないブランチを削除しようとするとエラーになる もしどうしても削除したいのなら「-D」オプションをつけろ
  17. 25 44 ブランチの削除 main HEAD もし削除したら? コミットは失われない しかし、既存のブランチからたどれなくなる mainブランチからたどれるコミット 各コミットは「親コミット」を覚えている

    「親コミット」をたどることで自分のルーツを知ることができる 「子供コミット」は知らない マージされていないブランチを削除すると、たどれないコミットが生じる どのブランチからもたどれない
  18. 26 44 ブランチの削除 main old_branch new_branch new_branchからたどれるので git branch –d

    old_branchができる mainからたどれないので git branch –d old_branchができない 「マージされていないから削除できない」というエラーが 出る条件は「カレントブランチ」からたどれるかどうか カレントブランチがnew_branchの時は削除できる カレントブランチがmainの場合は削除できない $ git branch –d old_branch
  19. 27 44 衝突(コンフリクト) 分岐した歴史をマージする際、Gitは可能な限り、両方の修正を取り込もうとする main HEAD feature main HEAD $

    git merge feature 異なるファイルが修正されていたら、両方の修正を取り込む 同じファイルでも、修正箇所が重なってなければ取り込む
  20. 29 44 衝突(コンフリクト) mainとfeatureで同時にtest.txtを修正した状態でマージしようとした $ git merge feature Auto-merging test.txt

    CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result. • test.txtを自動マージしようとした • 衝突(CONFLICT)が発生した • 衝突を解決(fix)して、結果をコミットせよ Gitは衝突を検出すると、ユーザに解決を求める
  21. 30 44 衝突(コンフリクト) Hello merge! This line is modified on

    main. カレントブランチ (HEAD)でのtest.txt featureブランチ でのtest.txt Hello merge! This line is modified on feature. マージに失敗し、衝突状態のtest.txt Hello Merge! <<<<<<< HEAD This line is modified on main. ======= This line is modified on feature. >>>>>>> feature ここがHEADではこう なってるけど featureブランチではで はこうなってるよ
  22. 32 44 マージと衝突のまとめ マージとは何か • 分かれた歴史を一つにまとめる作業 • 合流点を「マージコミット」と呼ぶ • マージしたいブランチが直系の子孫である場合はブラ

    ンチの移動でマージが完了する(fast forwardマージ) 衝突とその解決 • 自動でマージコミットを作れない状態を衝突と呼ぶ • ユーザはマージコミットのあるべき姿をインデックス に登録、コミットする
  23. 34 44 リベース main branch HEAD c1 c2 c1’ c2’

    $ git rebase main + + + + branch HEAD main
  24. 35 44 リベース main branch HEAD main branch HEAD $

    git rebase branch branchブランチのベース(赤丸)を、mainブランチの指すコ ミットに張り替えたように見えるのでリベース 移動しているのは「線(パッチ)」であってコミットではない コミットは新たに作られる
  25. 36 44 リベース Alice Bob main feature_B 機能Aを実装 機能Bを実装 mainにマージ

    • mainブランチから、Aliceがfeature_Aを、Bobがfeature_Bを分岐 • Aliceが機能Aを実装してmainにマージ(fast-forward) • Bobが機能Bを実装してmainにマージ(non-fast-forward)
  26. 37 44 リベース • mainブランチから、Aliceがfeature_Aを、Bobがfeature_Bを分岐 • Aliceが機能Aを実装してmainにマージ(fast-forward) • Bobが機能Bを実装してmainへリベース •

    feature_Bがfast-forwardマージ可能になる main feature_B main feature_B main rebase merge 機能A を実装 機能B を実装 順番に開発したような歴史が作られた
  27. 38 44 リベース HEAD main feature_A A1追加 A2追加 Doc追加 フィーチャーブランチをそのままmainにマージすると

    「中途半端な状態のコミット」が残ることがある このままfast-forwardマージすると、「途中経過」も歴史に残る mainブランチは「常にきれいな状態」であって欲しい 機能A実現のためのサブタスク
  28. 39 44 リベース HEAD main feature_A A1追加 A2追加 Doc追加 HEAD

    main feature_A 機能A追加 + マージする前にコミットをまとめて歴史を整理しておく 歴史の整理にもリベースを使う
  29. 40 44 対話型リベース $ git rebase -i ブランチ名 pick d6f185f

    c1 pick b2b0b0b c2 # Rebase e9c8c91..b2b0b0b onto e9c8c91 (2 commands) エディタが開き、以下のような画面がでる リベースで移動するコミット候補が表示されており どのコミットをどうするか選ぶ pick : コミットをそのまま使う squash: コミットは使うが、前のコミットとまとめる コミットを破棄したり、並べ替えたりもできる
  30. 41 44 コミットのsquash c1 c2 $ git rebase –i main

    + + branch HEAD main + + c1’ c2’ pick c1 pick c2 + + pick c1 squash c2 + + + c1’
  31. 42 44 リベース中の衝突 main branch HEAD c1’ c2’ + +

    移動するコミットの数だけ衝突する可能性がある リベースは「ベース」となるコミットに次々と 修正を適用すること操作 「次に作られるべきコミット」をインデックスに 登録してコミットを繰り返す