Slide 1

Slide 1 text

detached HEADを理解して 脱Git初⼼者を⽬指す⽅のための Git⼊⾨勉強会 @サポーターズCoLab ミクシィグループ 株式会社Diverse 新規サービス事業部 Poiboyグループ 今泉智博 (2018/02/06)

Slide 2

Slide 2 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 3

Slide 3 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 4

Slide 4 text

自己紹介 今泉智博 (@imaizume ) 株式会社 in iOS版の開発を担当 よく使うコマンドはrebase -i & add -p 今年はノーラーメン&COMPで-5kgを達成 2/20に学生向けLT会出ます(&もあるよ❗) (https://mixi-recruit.snar.jp/jobboard/detail.aspx?id=fuEGYRyWOsM)

Slide 5

Slide 5 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 6

Slide 6 text

本題の前に みなさんに質問です

Slide 7

Slide 7 text

❓ Git を不自由なく使えていますか ❓ Gitコマンドをいくつ知っていますか ❓Git を仕事/プロジェクトで使っていますか

Slide 8

Slide 8 text

Gitを便利にするツールたち (ただしGUIツールを除く)

Slide 9

Slide 9 text

tig (コマンドラインツール) addとcommitが j/k/u/1/Enter のみで完結

Slide 10

Slide 10 text

git alias (ショートカット設定) @imaizumeは166 alias設定していました

Slide 11

Slide 11 text

gitignore with gibo さらに”git” は “g” にaliasできる! (参考記事)

Slide 12

Slide 12 text

正しく便利設定をして 操作量とミスを減らしましょう

Slide 13

Slide 13 text

でも今日は これらの便利設定 あえて使いません (コマンドを理解してもらいたいので)

Slide 14

Slide 14 text

では本題

Slide 15

Slide 15 text

⬇ Gitの操作に慣れてきたあなた gitなんて楽勝だわー branch切ってaddしてcommitして pushするだけだもんね〜

Slide 16

Slide 16 text

…しかしある日

Slide 17

Slide 17 text

そのメッセージは突然現れた

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

_人人人人人人人人人人人人_ > 突然の detached HEAD <  ̄YYYYYYYYYYYY ̄ \(^o^)/

Slide 21

Slide 21 text

ウッ… どうすればいいんだっけ…

Slide 22

Slide 22 text

ネットで調べて その場では解決する

Slide 23

Slide 23 text

でも ちゃんと本質理解してますか❓

Slide 24

Slide 24 text

ggrks 面倒だけど 検索するか… その場しのぎの 知識を得ます 一時的に万能感を 覚えます すぐに 忘れます 前にググったはずなのに 思い出せない!! もう一回 検索だ!! テンプレ以外の対応が できなくなります

Slide 25

Slide 25 text

こうならないように 今日しっかり覚えましょう

Slide 26

Slide 26 text

実は detached HEADを理解すると Gitとより仲良くなれる

Slide 27

Slide 27 text

ブランチに縛られないで commit間を自由に移動できる❗

Slide 28

Slide 28 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 29

Slide 29 text

本日のゴール Detached HEADを恐れない detached HEADを理解する

Slide 30

Slide 30 text

本日のサブゴール そのため必要なこと… branchとHEADの正しい理解

Slide 31

Slide 31 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 32

Slide 32 text

基礎的なGitコマンド ⭐git init ⭐git status ⭐git add git commit [-m] git checkout [-b] git branch 今日の講義でよく使います‼

Slide 33

Slide 33 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 34

Slide 34 text

git branchについて 正しく理解していますか❓

Slide 35

Slide 35 text

よくあるbranchの説明 001 002 master > git init && git commit > git commit 003 > git branch dev && git checkout dev > git commit dev 004 > git checkout master 005 > git commit > git checkout dev > git commit branch is コレ

Slide 36

Slide 36 text

ではこんな場合は❓

Slide 37

Slide 37 text

分岐前の部分 001 002 master 003 dev 004 005 branch is … アレ ❓ 分岐前の部分を 図的に入れ替えてみた (履歴は前の図と同じ)

Slide 38

Slide 38 text

同一commitで複数branch作成 001 master dev > git checkout master > git checkout -b dev > git checkout -b test > git checkout -b feature feature test branch is ドレ❓

Slide 39

Slide 39 text

マージした/されたブランチ 001 002 master 003 004 005 > git merge dev dev > git checkout master 006 master branch is コレ❓

Slide 40

Slide 40 text

Q: 結局branchって何なの❓

Slide 41

Slide 41 text

A: commitを指すポインタ

Slide 42

Slide 42 text

「ポインタ」と聞いて連想するものは❓

Slide 43

Slide 43 text

C言語ですよね (他言語での「参照渡し」も同様) char型のポインタpを作成 > char *p = “clang” c l a n g \0 p

Slide 44

Slide 44 text

002 master branch=commitへのϙΠϯλ 001 実はgitの「ポインタ」も本質は同じ > git branch master

Slide 45

Slide 45 text

git branch の正体 ⭐ さらにざっくり言えば 「branch = commitの別名」 (⾠コマンドの実行結果は異なるので注意) よくある勘違いの原因 「branch ≠ コミット群」
 左の例では • master は004を指すポインタ • devは 005を指すポインタ 001 002 master 003 dev 004 005 ここを詳しく深掘り

Slide 46

Slide 46 text

branchへcommitを積んだ時のgit内部の動き master 001 002 > git checkout master (操作対象をmasterに切り替え) > git commit -m “fix bugs” (masterが指しているcommit 001に新しいcommitを積むよ) (新しいcommit 002を作るね、親は001だよ) > [master 002] fix bugs (masterの指す先を002に更新するよ) ポイント branchが指すcommitは 自動で更新される

Slide 47

Slide 47 text

commitへcommitを積んだ時のgit内部の動き 002 001 > git checkout 001 (操作対象を001に切り替え) > git commit -m “fix bugs” (commit 001に新しいcommitを積むよ) (新しいcommit 002を作るね、親は001だよ) > [HEAD 002] fix bugs (操作対象を002に更新するよ) ポイント branchが指すcommitは 自動で更新されない ❌ ※同じIDのbranchとcommitへの操作結果 コードの状態は同じ git上の状態は異なる master

Slide 48

Slide 48 text

branchを無事に攻略 カンタンでしたね‼ 「branchはcommitへのポインタ」 と覚えておきましょう

Slide 49

Slide 49 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 50

Slide 50 text

ところでみなさん お気づきですか❓

Slide 51

Slide 51 text

master 001 002 master 002 001 ⬅ こいつは一体何者⁉

Slide 52

Slide 52 text

Q: 「自分が今見ているcommit」 をGitではどう表現するの❓

Slide 53

Slide 53 text

A: HEADͱ͍͏ϙΠϯλͰදݱ

Slide 54

Slide 54 text

git HEAD の正体 ⭐ HEAD=「自分が今見ている commit/branchを指すポインタ」 ⭐ gitでは特殊な存在 左の例では • HEADはmasterを指す • masterはcommit 004を指す • devはcommit 005を指す 001 002 master 003 dev 004 005 (HEADのN commit前を ”HEAD~N” のように表現) HEAD

Slide 55

Slide 55 text

改めてgit commitで起きること > git checkout master [NEW] (操作対象HEADをmasterに切り替え) > git commit -m “fix bugs” (masterが指しているcommit 001に新しいcommitを積むよ) (新しいcommit 002を作るね、親は001だよ) > [master 002] fix bugs (masterの指す先を002に更新するよ) [NEW] (HEADが指している先はmasterだな) master 001 002 HEAD [NEW] (HEADが指している先は変えないよ) commitを含む 全てのgitコマンドは HEADを通じて実行されている

Slide 56

Slide 56 text

HEADも攻略 これもカンタンでしたね‼ 「HEAD = 今見ているcommit/branchへのポインタ」 と覚えておきましょう

Slide 57

Slide 57 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 58

Slide 58 text

Git branch の正体 ついに…本日のテーマである detached HEADの解説です⚔

Slide 59

Slide 59 text

Q: ズバリdetached HEADとは❓

Slide 60

Slide 60 text

A: HEADが branchを指していない状態

Slide 61

Slide 61 text

お疲れ様でした detached HEADの解説 以上❗

Slide 62

Slide 62 text

あっさりすぎるので一応補足 • branchをcheckoutしている間はdetached HEADしない • commitをcheckout (or rebase途中等)でdetached HEADする • detached ➡ attached へ戻りたければ 1.ブランチをcheckoutする (e.g. git checkout master) 2.その場でブランチ作る (e.g. git checkout -b new-branch) 001 HEAD ➖detached HEAD master 001 HEAD ➕attached HEAD

Slide 63

Slide 63 text

もっと詳しく:.gitディレクトリ “HEAD” と “refs/heads/xxxx” の中身は?

Slide 64

Slide 64 text

imaizume@mac ~/dots (master) $ git checkout HEAD~1 Note: checking out 'HEAD~1'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b HEAD is now at 8952c2c... Update Readme imaizume@mac ~/dots (cdc8446) $ cd .git imaizume@mac ~/dots/.git (cdc8446) $ ls -a . COMMIT_EDITMSG HEAD branches description index logs packed-refs tags.lock .. FETCH_HEAD ORIG_HEAD config hooks info objects refs imaizume@mac ~/dots/.git (cdc8446) $ cat HEAD cdc84468952c2cb2c8cebe819cbea64f0654eae4 imaizume@mac ~/dots/.git (cdc8446) $ cat refs/heads/master 40f1d950027fd7d2efbba17576402610adf1e6cc commit を checkout した状態 (detached HEAD) HEAD =/=> master

Slide 65

Slide 65 text

imaizume@mac ~/dots (master) $ git checkout master Already on 'master' Your branch is up-to-date with 'origin/master'. imaizume@mac ~/dots (master) $ cd .git imaizume@mac ~/dots/.git (master) $ ls -a . COMMIT_EDITMSG HEAD branches description index logs packed-refs tags.lock .. FETCH_HEAD ORIG_HEAD config hooks info objects refs imaizume@mac ~/dots/.git (master) $ cat HEAD ref: refs/heads/master imaizume@mac ~/dots/.git (master) $ cat refs/heads/master 027fd7d2efbba17576402610adf1e6cc40f1d950 branch を checkout した状態 (attached HEAD) HEAD => master 内部構造をもっと詳しく知りたい方は ”Pro Git 第10章”をご参照ください

Slide 66

Slide 66 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 67

Slide 67 text

事例1: 差分の影響を調べる • HEADでバグが発生 • ちょっと(1commit)前に戻りたい • 問題なかったら元のcommit (branch)へ戻りたい • よってgit resetするのは嫌 • 直前のコミットをcheckout(してビルド)する • 一時的にdetached HEAD状態になる • 手軽に差分の影響を調べられる C1 a C2 C1 a C2 HEAD HEAD 少し前に戻って 状態を再現したい

Slide 68

Slide 68 text

事例2: branchの再作成 • 作業中誤ってブランチ(a)を消してしまった‼ • 既に違うブランチ(b)に移動済み • しかもgithubにもpushしていない… • お助けコマンド: git reflog • HEADが指していたcommitの履歴を表示 • 一旦HEADをdetach • C2へ移動後にbranch再作成!! b C3 C2 a C1 HEAD C3 C2 C1 b C2に戻りたい!

Slide 69

Slide 69 text

事例3: ブランチの強制移動 • 今のブランチ(a)を一旦破棄したい • その際既存ブランチ(b)にそのまま(a)を移動したい • git branch -f を使う • 強制的にブランチをHEADへポイント • リモートへpush済みの場合conflictに注意 • 「ブランチ=ポインタ」の構造を知っていれば簡単 • 再びC2に戻りたい時は事例2の手順でOK C1 a b C3 C2 C1 a C3 C2 b C2を破棄して bに合わせたい! HEAD

Slide 70

Slide 70 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 71

Slide 71 text

本日のまとめ branch = commitを指すポインタ HEAD = 自分が見ている commit/branchを指すポインタ detached HEAD = HEADがbranchを指していない状態 detached HEADは怖くない! branchから解放されてcommitを自由に飛び回ろう

Slide 72

Slide 72 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 73

Slide 73 text

関連記事/参考資料 jonas/tig simonwhitaker/gibo peco と alias -g で git に便利革命おきた - Qiita detached HEAD から脱出する方法を git の 内部構造から探る - Qiita Pro Git

Slide 74

Slide 74 text

イベント告知: mixi GROUP Tech Meet ! ミクシィグループ17新卒5名によるLT&交流会 入社経緯や仕事、技術等を語ります 美味しいご飯とお酒も提供予定 採用ページにて告知中 (2月18日応募締切り)

Slide 75

Slide 75 text

イベント予告: git challenge 毎回「現場あるある」なGitの問題を出題 実際にコマンドを叩いて解答、獲得点数を競う 第2回からGitHub Japanさんが公式スポンサーに ❗ 次回は未定です...が決まり次第弊社採用ページで告知予定

Slide 76

Slide 76 text

INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー

Slide 77

Slide 77 text

当日頂いた質問と回答 (1) Q: branch ではなくcommitにcommitを積む場面はあるのか❓ A: 正直あまりないです(解説したのにすみません…) HEADの少し手前から試行錯誤で別のcommit系列を積んで 確信が得られたらブランチにするとかはあるかもしれません。 Q: gitを上達したいです❗…がどうすればよいですか A: 自分の経験では以下の3つを意識すると良いかもです。 1. 何よりも実務/プロジェクトで触る (必要性があると覚える) 2. コマンドを覚えたらオプションも調べましょう (結構有益) 3. 近くにgitのメンターを(直接対面で聞いた方が良いことも多い)

Slide 78

Slide 78 text

当日頂いた質問と回答 (2) Q: gitのコミットはファイルを保存しているの入っていない❓ A: gitが管理しているのは「差分だけ」です。 内部的に差分はcommit単位で.git/objects以下に保存されます。 gitコマンドを叩くと裏では.git/objectsから 差分情報を読み出したり保存したりしているのです。 Q:”fix bugs” というコメントはなぜダメなのでしょうか❓ A: 読み手に親切な表現ではないのです。 コミットメッセージは他人(or 未来の自分)が読んで 差分を見ずに変更の概要を把握できるべきです。 なので「具体性のあるメッセージが望ましい」という意味でした

Slide 79

Slide 79 text

当日頂いた質問と回答 (3) Q: きれいなコミットメッセージを書くコツは❓ A: 粒度の小さなコミットを積むと良いでしょう。 1000行の差分を一言で表すのは難しいですが 2,3行なら自分が何をしたかすぐ説明できるはずです。 あとは変更の内容に理由を合わせて書くのが良いでしょう。 おすすめは git add -p で小さな commit を作り その後 git rebase -i で意味ごとに整列/結合する方法です。

Slide 80

Slide 80 text

No content