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

(再演) detached HEADを理解して脱Git初心者を目指す方のためのGit入門勉強会 @サポーターズCoLab

(再演) detached HEADを理解して脱Git初心者を目指す方のためのGit入門勉強会 @サポーターズCoLab

1a74617b91d2757b839b9cf3614648ce?s=128

Tomohiro Imaizumi

September 14, 2018
Tweet

Transcript

  1. detached HEADを理解して 脱Git初⼼者を⽬指す⽅のための Git⼊⾨勉強会 サポーターズCoLab勉強会 @imaizume

  2. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

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

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  4. 今泉 智博 @imaizume 2017年株式会社ミクシィ新卒入社 株式会社 所属 iOS利用経験0から iOS版開発担当に (ほぼ)毎日健康COMP生活はもうすぐ1周年 自己紹介

  5. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  6. ❓ Git を不自由なく使えていますか ❓ Gitコマンドをいくつ知っていますか ❓Git を仕事/プロジェクトで使っていますか みなさんに質問です

  7. gitコマンドの操作を助ける 便利ツールの紹介 不慣れな方も大丈夫!

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

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

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

  11. 今日は便利設定は使いません (コマンドを理解してもらいたいので) (個人使用は推奨 気になる方は懇親会で)

  12. では本題

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

  14. …しかしある日 そのメッセージは突然現れた

  15. None
  16. None
  17. _人人人人人人人人人人人人_ > 突然の detached HEAD <  ̄YYYYYYYYYYYY ̄ \(^o^)/

  18. ウッ… どうすればいいんだ…

  19. ネットで調べて その場では解決するが…

  20. ちゃんと本質理解してます❓

  21. ggrks 面倒だけど 検索するか… その場しのぎの 知識を得ます 一時的に万能感を 覚えます すぐに 忘れます 前にググったはずなのに

    思い出せない!! もう一回 検索だ!! テンプレ以外の対応が できなくなります
  22. こうならないように 今日しっかり覚えましょう

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

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

  25. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  26. 本日のゴール Detached HEADを恐れない detached HEADを理解する

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

  28. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  29. 基礎的なGitコマンド ⭐git init ⭐git status ⭐git add git commit [-m]

    git checkout [-b] git branch 今日の講義でよく使います‼
  30. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  31. git branchについて 正しく理解していますか❓

  32. よくある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 コレ
  33. ではこんな場合は❓

  34. 分岐前の部分 001 002 master 003 dev 004 005 branch is

    … アレ ❓ 分岐前の部分を 図的に入れ替えてみた (履歴は前の図と同じ)
  35. 同一commitで複数branch作成 001 master dev > git checkout master > git

    checkout -b dev > git checkout -b test > git checkout -b feature feature test branch is ドレ❓
  36. マージした/されたブランチ 001 002 master 003 004 005 > git merge

    dev dev > git checkout master 006 master branch is コレ❓
  37. Q: 結局branchって何なの❓

  38. A: commitを指すポインタ

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

  40. C言語ですよね (Java等での「参照渡し」も同様) char型のポインタpを作成 > char *p = “clang” c l

    a n g \0 p
  41. 002 master branch=commitへのϙΠϯλ 001 実はgitの「ポインタ」も本質は同じ > git branch master

  42. git branch の正体 ⭐ さらにざっくり言えば 「branch = commitの別名」 (⾠全く同じものではないことに注意) よくある勘違いの原因

    「branch ≠ コミット群」
 左の例では • master は004を指すポインタ • devは 005を指すポインタ 001 002 master 003 dev 004 005 ここを詳しく深掘り
  43. 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は 自動で更新される
  44. 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
  45. branchを無事に攻略 カンタンでしたね‼ 「branchはcommitへのポインタ」 と覚えておきましょう

  46. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  47. ところでみなさん お気づきですか❓

  48. master 001 002 master 002 001 ←こいつは一体何者⁉ (こいつ=操作対象のコミット)

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

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

  51. 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
  52. 改めて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を通じて実行されている
  53. HEADも攻略 これもカンタンでしたね‼ 「HEAD = 今見ているcommit/branchへのポインタ」 と覚えておきましょう

  54. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  55. Git branch の正体 ついに…本日のテーマである detached HEADの解説です⚔

  56. Q: ズバリdetached HEADとは❓

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

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

  59. あっさりすぎるので一応補足 • 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
  60. もっと詳しく:.gitディレクトリ “HEAD” と “refs/heads/xxxx” の中身は?

  61. 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 <new-branch-name> 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
  62. 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章”をご参照ください
  63. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  64. 事例1: 差分の影響を調べる • HEADでバグが発生 • ちょっと(1commit)前に戻りたい • 問題なかったら元のcommit (branch)へ戻りたい •

    よってgit resetするのは嫌 • 直前のコミットをcheckout(してビルド)する • 一時的にdetached HEAD状態になる • 手軽に差分の影響を調べられる C1 a C2 C1 a C2 HEAD HEAD 少し前に戻って 状態を再現したい
  65. 事例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に戻りたい!
  66. 事例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
  67. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  68. 本日のまとめ branch = commitを指すポインタ HEAD = 自分が見ている commit/branchを指すポインタ detached HEAD

    = HEADがbranchを指していない状態 detached HEADは怖くない! branchから離れてcommitを自由に飛び回ろう
  69. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  70. 関連記事/参考資料 jonas/tig simonwhitaker/gibo peco と alias -g で git に便利革命おきた

    - Qiita detached HEAD から脱出する方法を git の 内部構造から探る - Qiita Pro Git
  71. 宣伝(1/3): Diverseは採用強化中! Server / Android / iOS エンジニア大募集 ❗ スピード感とチャレンジを大切に開発

    会社見学・面接のお問合せお気軽にどうぞ 個別に社員へDMいただいてもOK https://www.wantedly.com/companies/diverse-inc
  72. 宣伝(2/3): Diverseが勉強会を開催! 「マッチングサービス開発の裏側Night」開催決定 09/28(金) 19:00開始 会場は渋谷駅周辺を予定 https://diverse.connpass.com/event/100488 マッチングサービス開発現場で実際に起きたリアルな話、 アプリを支える技術の裏話などなどが聞けます

  73. 宣伝(3/3): ブログ&Podcastもやってます 開発ブログ: https://developer.diverse-inc.com/ エンジニア社員の各種勉強会への登壇情報や開発に 関する記事を更新中 Podcast: https://podcast.diverse-inc.com/ Diverseでのサービス開発や組織等にまつわる話を 社員のリアルなトークでお伝えするPodcast

  74. INDEX 自己紹介 プロローグ 本日のゴール Git の基礎コマンド復習 Git branch を理解しよう Git

    HEAD を理解しよう Detached HEAD を理解しよう 事例紹介 & 演習時間 本日のまとめ 参考リンク & お知らせ 質問コーナー
  75. 前回の質問と回答 (1) Q: detached HEADでcommitを積む場面はあるの❓ A: 正直あまりないです(解説したのにすみません…) HEADの少し手前から試行錯誤で別のcommit系列を積んで 確信が得られたらブランチにするとかはあるかもしれません。 Q:

    gitを上達したいです❗どうすればよいですか❓ A: 確実なアドバイスではないですが 1. 実務やプロジェクトで触る (必要性を作る なければ導入から) 2. コマンドのオプションも調べる (知らないものが多くて有益) 3. 頼れるgitメンターを見つける(対面で聞く方が良いことも多い)
  76. 前回の質問と回答 (2) Q: gitのコミットはファイルを保存しているの入っていない❓ A: gitが管理しているのは「差分だけ」 内部的に差分はcommit単位で.git/objects以下に保存されます gitコマンドを叩くと裏では.git/objectsから 差分情報を読み出したり保存したりしているのです Q:”fix

    bugs” というコメントはなぜダメなのでしょうか❓ A: 読み手に親切な表現ではないのです。 コミットメッセージは他人(or 未来の自分)が読んで 差分を見ずに変更の概要を把握できるべきです。 なので「具体性のあるメッセージが望ましい」という意味でした
  77. 前回の質問と回答 (3) Q: きれいなコミットメッセージを書くコツは❓ A: 粒度の小さなコミットを積む意識を 1000行の差分1つよりも2,3行の変更を100個 git add -p

    でcommit & git rebase -i で整列/結合がおすすめ きれいなcommit勉強会の資料も御覧ください https://speakerdeck.com/imaizume/zuo-ritaifang- falsetamefalsegitmian-qiang-hui
  78. None