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

Git研修1

techtekt
August 23, 2023

 Git研修1

パーソルキャリア株式会社 テクノロジー本部 エンジニアリング統括部 サービス開発部
※本資料は2023年3月時点の情報であり、当該部門における2023年新卒の研修教材です。

techtekt

August 23, 2023
Tweet

More Decks by techtekt

Other Decks in Programming

Transcript

  1. この研修について • みなさんが業務で GitHub を使う際に必要な最低限の情報を入れ込んでいます • 既に知っているところ、知らないところそれぞれあると思います • 長いのでマメに休憩を入れます 気になることがあったときは

    🤔 • わからない、気になるところはメッセージや口頭で教えてください! • 知らないことや苦手なことを共有するのは信頼関係構築でも重要です 󰢏 • 知らないから見下す、という認識の人はサビ開にいません • 知らないことを知らないと言える人がいちばん偉い
  2. もくじ 前半 Git を使ったチーム開発に関する Tips • 概念やサービス開発部での開発作法に関するもの中心 後半 Git 自体の概念や仕組み理解

    • branch とは? HEAD って? commit って何? • rebase とは? merge / rebase の違いは? • conflict したときどうする? • その他コマンドについて
  3. Gitってなに? • 分散型バージョン管理システム ( DVCS ) の一つ • Linux カーネルの開発において使用するために、Linus

    Torvalds によって 2005年に開発された 分散型 各開発者がリポジトリの完全なコピーをローカルに持つ ↔ 中央集中型 バージョン管理システム ファイルの変更履歴を追跡し、異なるバージョン間の差分や統合を管理するソフトウェア
  4. Git 以外のバージョン管理システム • Subversion (中央集中型) • Mercurial (分散型) • CVS

    (中央集中型) • Perforce (中央集中型) など Git 以外を使う理由 • 長期でシステムを運用している場合、移行のリスクやコストを避けるため • ゲーム開発や映像制作など、バイナリファイルを多用するプロジェクトでは、 Perforce が適しているため
  5. 1. アサインされたイシューに対して作業ブランチを作成 • 基本的には 1つのイシューに 1つのブランチ イシューの File Changed が多くなってしまいそうな時は

    2回に分けることも • ブランチ名について ◦ HiPro Direct の場合... ◦ 新機能の場合は feat/{issue番号}/{機能に関するワード} (ex : feat/1324/create_user) ◦ 修正タスクの場合は fix/{issue番号}/{機能に関するワード} ◦ プロジェクトによるので、プロジェクト配属後に確認しましょう!
  6. 2. 作業ブランチに commit、push • 何か 1つが動作する状態で commit すると良い • commit

    数が多い/ Git の草の色が濃い ≠ 偉い • commit 数が評価対象になることはありません!
  7. 2. 作業ブランチに commit、push • commit メッセージはわかりやすいものに Good 👍 「feat :

    ユーザー登録機能実装」「fix : ログイン時のバグ修正」 Bad 😞 「asdf」、「hogehoge」、「test」 など • Prefixを付けることが多い 新機能なら feat、修正なら fix など 参考 : https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type プロジェクトによっては絵文字を付けたりする
  8. 2. 作業ブランチに commit、push • push は慎重に ◦ push 先が間違っていないか確認しましょう ◦

    force push は基本的にしない 󰢂 ◦ が、例外もある ◦ コンフリクト解消する時や rebase した時
  9. 3. PR 作成、レビュー、マージ • PR は、基本的には issue の要件が完成したら作成します • 内容共有などのために他の人に見せたい時は

    Draft 機能を使いましょう • PR Open = 完成して見てもらえる状態である と考えましょう 追加変更が必要になったら? • 追加の変更が必要になった場合は別 PR にするのがいいかも ◦ 変更が大きすぎてレビューコストが増えることを避けるため ◦ PR の対応範囲(スコープ)を明確にするため
  10. 3. PR 作成、レビュー、マージ PR 作成時にやること 1. ルールに沿ったタイトルをつける 2. merge 先ブランチを指定する

    3. 詳細を記入する ◦ 対応する issue は何か? ◦ 具体的にどのような変更をしたのか? ◦ 動作確認はどのようにしたのか? 4. (あれば)レビュアーに対してコメントを書く PR のルールはプロジェクトごとに異なるので配属時に確認しましょう!
  11. 3. PR 作成、レビュー、マージ レビューで ChangeRequest がきた! • 落ち着いて指摘内容を確認し、修正していきましょう • 相手の指摘自体が間違っていることもあるため、

    言われたまま修正するのではなく、自分で考えて直しましょう • レビュアーが偉い or 絶対正しいなどはないので自信を持って確認しましょう
  12. 3. PR 作成、レビュー、マージ レビューで ChangeRequest がきた! • 修正が終わったら変更した旨をレビュアーに返信 + Reviewers

    の🔁をクリックしましょう • 「修正しました!+ commit の URL 」としておくと親切です • 文字でのやり取りだと冷たく感じることがあります。コメントする際の言葉遣いは 気をつけましょう • たくさんコメントがつくことは恥ずかしくない どんどん CR 受けましょう!
  13. Approveされた! • merge するには 2人の Approve が必要な場合が多い • merge は

    Auto-merge /レビュアーがマージ/ Author がマージ…( PJ による) • merge の種類はいくつかあります ◦ Create a merge commit ◦ Squash and merge ◦ Rebase and merge • プロジェクトによってどの merge にするかは異なる場合があるため 先輩に確認しましょう!
  14. 質問する際に気をつけること • どの issue に関する質問なのか(ex. issue301 のXXの API 追加について) •

    何を解決しようしたのか(ex. XXができるような処理を書こうとした) • 何で詰まったのか(ex. ZZというエラーが出てうまくいかない) • 自分で既に試したことは何か?(ex. このサイトにある方法を試してみた) • どう助けて欲しいのか?(ex. エラー見て欲しい、いい実装例を知りたい) • 必要に応じて画面共有すると伝わりやすいです
  15. コードと動作の両方の確認を • comment をつける時はコード引用形式で書きましょう • Change Request なのかそこまでではない意見 (in my

    opinion) なのか明確に 「must」「imo」「nits」「Q」など • 指摘の際は「なぜ」「どのように」を明確に書きましょう • コメントは受け手にはきつい言葉のように捉えられやすいので 言葉選びには気をつけましょう
  16. repository を fork しよう 前提条件 • GitHub で SSO が完了している

    • 使用している PC から Git に SSH できる状態にある Git SSH について • ここをみてね GitHub に SSH で接続する - GitHub Docs
  17. repository を fork しよう 1. https://github.com/pcae/2023-git-training を開く 2. 右上の [

    fork ] をクリックし、自分の名前を追加して fork する
  18. repository を fork しよう 1. GitHub から SSH を選択して URL

    をコピー 2. 適当なディレクトリに git clone <コピーしたURL>
  19. ハンズオンの流れ Git の概念や仕組み理解 1. branch とは 2. HEAD とは 3.

    commit とは 4. merge とは 5. conflict したときどうする? 6. rebase とは 7. その他コマンド
  20. 現在の branch を確認してみよう 1. git branch or GUI で確認する(•が白抜きになっている) 2.

    CLI でグラフィカルに見たい方は以下のコマンド git log --oneline --decorate --graph --all
  21. branch を作ってみよう 1. git branch test1 を実行し、test1 ブランチを作成 2. git

    log --oneline --decorate or GUI でブランチの状態を確認する 3. 同一コミットの横に branch名が増えている (が、枝分かれはしていない)
  22. • main, origin/main, origin/HEAD, test1 は全て 8d50a5c の横にある これだけではまだ branch

    がポインタであることがわかりづらいと思うので、 .git/refs/heads ディレクトリを確認していきます。 • .git/refs/heads ディレクトリって? リポジトリ内のすべてのローカル ブランチを定義しているフォルダ。 heads ディレクトリ直下に各ブランチ名のファイルが格納されており、 各ファイル内にはコミットハッシュがあります。 branch とは commit を指し示すポインタである...?
  23. test1 に checkout して commit しよう 1. git checkout test1

    を実行 2. test1 に commit してみる ◦ test/test.md と README.md に適当な文字を追加してください ◦ 変更を保存したら、fix: README.mdとtest.md修正 という commit メッセージで commit してください 3. git log --oneline --decorate or GUI で変化を確認 4. test1 の位置が移動している
  24. もう一度 .git/refs/heads/ を確認しよう 1. test1 をもう一度 catコマンドで開いてみる cat .git/refs/heads/test1 test1

    ファイルの commit ハッシュも変わっている branch とは commit を指し示すポインタである!
  25. • branch とは commit を指し示すポインタである ◦ branch は枝という意味だけれど実態はポインタ ◦ branch

    を作ると、どのコミットを指し示すかのポインタが作られる • .git/refs/heads ディレクトリで定義されている 「 branch とは」まとめ
  26. Git-flow って? Git におけるリポジトリの分岐モデルであり、ルー ルのこと。各ブランチを定義することで、複数人 での開発時に好き勝手にブランチが作成され混乱 することを防ぐ。 master (main) :

    本番用ブランチ develop : 開発用ブランチ feature : issue単位 (develop にマージ) release : リリース単位 (develop から切る) hotfix : 緊急修正 (master から切る) Developers IO.「Git-flowをざっと整理してみた」. https://dev.classmethod.jp/articles/introduce-git-flow/, (参照2023-04-10)
  27. .git/HEAD を確認してみよう 1. .git/HEAD が実態なので見てみる 2. test1ブランチで cat .git/HEAD …commit

    ハッシュじゃない🤔 branch ファイルを ref (参照)している HEAD → branch → commit
  28. checkout して .git/HEAD を確認してみよう 1. main に checkout してみましょう 2.

    git checkout main 3. cat .git/HEAD 中身が変わりました 😲 つまり、checkout は HEAD を任意の commit に動かすことである
  29. 1. この状態で git branch してみる HEAD detached at 😲 このまま

    commit すると checkout した瞬間その commit は宙に浮いてしまうので、 commit に checkout した場合、そこから branch を切ってから作業しましょう。 HEAD は branch を ref して commit を指している状態にしておく 2. git checkout main で main ブランチに移動しておきましょう ですが…注意
  30. commit を指しているところを見てみよう 1. checkout は HEAD を任意の commit に動かすことである →

    commit 自体にも checkout できる! 2. git checkout d03acbae (initial commit のハッシュ) 3. cat .git/HEAD で HEAD ファイルを確認する commitを指していますね 😌
  31. 「 HEAD とは」まとめ 1. HEAD とは現在作業中の commit を指すポインタである 2. checkout

    は任意の commit に HEAD を動かすこと 3. HEAD は branchファイルを介して commit を指し示すことで 作業ブランチを認識する itstaffing エンジニアスタイル「第19話 detached HEAD 状態って何?ブランチがない状態を解決する方法」. https://dev.classmethod.jp/articles/introduce-git-flow/,(参照2023-04-10)
  32. commit とは • ファイルの変更を記録したもの • commit オブジェクトに tree オブジェクトを保持している •

    スナップショット(※) を tree オブジェクトを介して参照している ※ 差分ではない
  33. commit の中身を見てみよう 1. .git ディレクトリには Git オブジェクト(.git/objects)が入っており、 それらが commit の実体

    2. .git/objectsを見てみる 3. cd .git/objects を実行 → ls -R を実行 commit 番号名のファイルを格納したフォルダが複数ある
  34. 1. git cat-file -t <フォルダ名 + commitハッシュ頭2桁 (c6a1)> でファイルの type

    を確認できる commit / tree / blob のどれかが表示されます commit の中身を見てみよう
  35. commit / tree / blob • commit : tree オブジェクト番号、親

    commit、author などの情報を持つ • tree : ディレクトリのようなもの。blob ファイルが格納されている • blob : Git 管理対象のスナップショット
  36. commit と出力されるものを開いてみる • git cat-file -p c6a1 で開いてみる ( -p

    は pretty-print のこと) VSCode で見たものと似ていますね 😲 • tree オブジェクト、parent (親コミット)、author、commit メッセージ が含まれている
  37. tree オブジェクトを見てみよう 1. git cat-file -p < tree ハッシュ上4桁 (92a8)

    > 2. blob も開く git cat-file -p <blob のハッシュ上4桁> ファイルの中身が見えます 👀
  38. commit は差分ではなくスナップショット 1. git log --oneline --decorate --graph --all or

    GUI で feat: test.md作成 の commit ハッシュを確認します 2. git cat-file -p <1で確認したハッシュ> を実行
  39. commit は差分ではなくスナップショット 1. git cat-file -p < tree ハッシュ >

    で中を見てみます README.mdはこの commit では変更していないはず 😐 commit は差分ではなくスナップショットであるため、 commit した時のファイルの状態を丸ごと持っています もっと詳しく知りたい方はこちらを参考にしてください 👇 https://github.blog/jp/2021-01-06-commits-are-snapshots-not-diffs/
  40. 「parent (親 commit) 」について 1. commit は常に親を指すポインタを持つ (first-commit は例外) 2.

    git log やGUIで確認してみる 親を持つことにより、差分管理を可能にし、 さらに改ざんも難しくしている
  41. 「commit とは 」まとめ • commit はスナップショットを tree を介して参照している • tree

    はディレクトリ、blobはファイルの内容 • commit は「差分」ではなく「スナップショット」 • 初回 commit を除いて、全ての commit は親を持つ
  42. 下準備 1. git checkout main を実行し、cd ../../ でgit-training-[自分の名前]ディレクト リ直下に移動しましょう 2.

    test フォルダ直下に test2.md ファイルを作ってコミットしておきましょう 3. このような状態になっていれば OK 👌
  43. merge してみよう 1. …の前に、現時点での commit の状態をスクショしておきましょう main ブランチと test1 ブランチの

    commit 番号が確認できれば良いので GUI でもCLI git log --oneline --decorate --graph --all でも OK です! 2. main ブランチにいることを確認して、git merge test1 を実行し、 test1 を main ブランチに merge しましょう
  44. branch の状態を確認する 1. 先ほどのスクショを確認し、test1 ブランチと main ブランチそれぞれの commit 番号が変わっていないことを確認しましょう 2.

    main ブランチには親ブランチが 2つあることを確認しましょう 3. merge とは、取り込み先のブランチに新しい commit を作ること
  45. conflict してみよう 1. sample_branch1 ブランチに checkout git checkout sample_branch1 2.

    main ブランチに checkout git checkout main 3. git merge sample_branch1
  46. わからなくなった時は 1. どう変更すればいいのかよくわからなくなることがある 2. そんな時は素直に merge を取り消し、やり直そう 3. conflict 解消中は

    git merge --abort merge しちゃった後は git reset --hard HEAD で merge 前に戻ることができ ます よくわからないけど merge!しないようにしましょう 😓 落ち着いてよく変更を見比べましょう 😉
  47. 「conflict した時どうする?」まとめ • conflict とは、異なる branch で行われた変更が同じ箇所に重なる場合に発生 する問題 • conflict

    を解消した場合はその変更を含んだ commit ができる • わからなくなった時は conflict 解消中は git merge --abort merge 後は git reset --hard HEAD で merge 前に戻れる • できるだけ conflict は起こさないようにしましょう 😮
  48. gitコマンド解説 • fetch : リモートブランチの履歴だけ取り込むこと • pull : リモートブランチを追跡ブランチに取り込むこと •

    stash : コミットしていない変更を退避させること • squash : 複数のコミットをまとめ、新しいコミットにすること • log : コミットログを確認すること • reflog : Git 操作全てのログを確認すること • reset : 任意の HEAD@XX まで branch の状態を巻き戻すこと
  49. merge • 2つの branch の最新コミットを親と する merge commit が作成される •

    統合した commit のハッシュ値は変 更されない (非破壊的変更) • コミット履歴が複雑になりがち merge と rebase の違い rebase • ある branch の変更履歴を別ブランチ の上に移動し、直線的なコミット履 歴を作成 • 新しい commit が作成され、commit のハッシュ値が変更される (破壊的変更) • コミット履歴が整理され、わかりや すくなる
  50. git pull git fetch + git merge git pull と

    git pull --rebase の違い git pull --rebase git fetch + git rebase
  51. rebase で注意すること • 現在の branch には破壊的変更が加えられ、commit も新しくなる → remote に

    push する際には force push が必要になる • 自分の作業ブランチ以外では行わない = public ブランチでは行わない • レビュー開始後は force push しない force push する前にそのブランチに checkout している人がいる場合、その人は git pull で差分を取り込むことができず、 git reset をする必要が出てくるため git reset コミットした内容を取り消すためのコマンド。 soft、mixed、hardなどのオプションがある。指定しなかった場合はデフォルトで mixed になる。 soft = HEAD、mixed = HEAD + インデックス、hard = HEAD + インデックス + ディレクトリ
  52. 流れ 1. main にチェックアウト (rebase start) 2. sample_branch2 の commit

    を一つずつ追加 (pick) commit され直すことになるので commit 番号が変わる 3. sample_branch2 のポインタの向き先は最後に pick された commit になり完了 sample_branch2の commit
 mainのcommit

  53. 「rebase とは」まとめ • merge と同じく変更内容を統合するためのもの • 直線的なコミット履歴を作成できる • commit のハッシュ値が変更される

    (破壊的変更) • 自分の作業ブランチ以外では行わない • レビュー開始後は force push しない • git pull = fetch + merge、git pull –-rebase = fetch + rebase