🫖

開発で出てきそうなGitの「なぜ?」まとめ

2023/12/25に公開

前提

  • 本記事は社内の開発メンバーの認識合わせを行うものです
  • メンバーのスキルとして以下を想定しています
    • Git、およびGitHubを用いたコードの管理をしたことがある
    • ブランチというものを知っており、「マージ」「プルリクエスト」「コンフリクト(競合)」の言葉を聞いたことがある
    • Git、およびGitHubを用いた商用案件(チーム開発形式)でコードがよく変更されたり頻繁な取り込みが必要になる
  • これに当てはまらない人はちょっと物足りなかったり逆に意味わからんってなったりするかもです
  • 本記事ではGitとGitHubの違いを説明するわけではないため、統一してGitという言い方をしています
    • 一部GitHubの機能に対して「Gitは...」という言い方をしている部分もあるかもですがご了承ください

言い訳

  • 本記事は以下が原因(言い訳)で未完全です
    • 私自身がGitやGitHubのことを完全に知っているわけではない
    • そもそもGitは奥が深い
    • 本記事の位置付けが「教科書」ではなく「参考にしていただた方々のさらなる発展要素の一助」としたい
  • 足りないところや発展要素は開発・勉強を通して共有をもらいたいです!
  • 上記の位置付けのため、本記事の内容は学術的根拠に基づいたものではなく一部経験説による断言も含まれていることをご了承ください!

書いてあること

  • なぜGitでコードを管理するのか
  • なぜmain(master)ブランチとdevelopブランチが存在しているのか
  • なぜGitで開発をするときに新たにブランチを切る必要があるのか
  • なぜプルリクエストを通してマージする必要があるのか
  • なぜforce pushは怖いのか
  • なぜブランチ削除はプルリクエストを作成後が良いのか

なぜGitでコードを管理するのか

https://zenn.dev/mt5/articles/20e56dfed15cb5 に記載してあることと重複するので割愛

なぜmain(master)ブランチとdevelopブランチが存在しているのか

※ あくまでも品質担保が必須となる例なので、全てのプロジェクトに当てはまるわけではないかもです
品質を担保したサービスの提供が求められている場合、一般的に以下のフローがある。

開発者での動作確認
↓
開発チーム他メンバーやテストチーム含む社内での動作確認
↓
提供(本番反映、リリース)

そのためには段階ごとのブランチが必要なので以下のように定義しているところが多い。
develop → 「開発チーム他メンバーやテストチーム含む社内での動作確認」で使用する資産を反映しておくもの
main → 現時点でエンドユーザーが見れる環境にあるもの

つまり、社内の動作確認はmainに入る前にできていないといけないし、developで動作確認ができていないものをmainに入れると品質担保できない。
上記の理由からmainへの反映はmain←developのプルリクエストのみ許容としているプロジェクトも存在する。

先述の通り品質担保以上に求められているもの(スピードや失敗体験の積み重ねなど)があるのであればその限りではないが、
品質が求められているのであれば上記およびそれに類似したフローは避けられないかもなぁ...と...。

なぜGitで開発をするときに新たにブランチを切る必要があるのか

前述のフローを採用するのであれば段階付けで以下のようにするため。

開発者での動作確認 // ここが新しいブランチ
↓
開発チーム他メンバーやテストチーム含む社内での動作確認 // ここがdevelop
↓
提供(本番反映、リリース) // ここがmain

また、複数人で開発している場合は

なぜプルリクエストを通してマージする必要があるのか

  • 直pushとの違いを分かりやすくする
  • ブランチ単位での差分が確認できる
  • 内容や他要素も合わせて伝えることができる
  • 競合が分かりやすい

直pushとの違いを分かりやすくする

添付画像を見てどれが直pushしたもの、どれがブランチからマージしたものか分かるでしょうか??

実は最新のcommitだけPCで git merge [featureブランチ] をしたものです。
このコマンドでマージをするとこの表示になります。
※ 複数commitだと分かりやすく見えるのかも、検証できてないです!

プルリクエストを用いた機能でマージした後は


見たいな表示なり、PRの2番でマージしたのかぁというのがcommitsから明らかにできます。

ブランチ単位での差分が確認できる

厳密にいうとPR単位です。
先ほどの内容で「そもそも直pushの運用ルールがなければいいのでは...??」と思った方もいるかもですが、
PRを通せば「さっきマージした内容でどのファイルに何の差分が発生したのか」が一目瞭然になります。
commit単位でちまちま追う必要もなく、何かトラブルがあったときにののPR部分を戻せば何とかなりそうという目安にもなります。

内容や他要素も合わせて伝えることができる

今回の変更で何がしたいのかということをコミットメッセージ以外で伝える場所があるというのは結構便利です。

特にタスク管理をしているとそのURLを貼っておいたりすることもできます。

競合が分かりやすい

マージ先のブランチとの差分を見て競合が発生している場合にはマージを阻止してくれます。
これにより意図しない上書きなどを防ぐことができます。

なぜforce pushは怖いのか

競合解消手段として「自分のPCで競合を直してforce pushをする」という手段があります。
ただ、mainやdevelopなど複数人の変更が入っているものに対してのforce pushは注意が必要です。
forch pushをすることで競合解消 = 上書きすることができますが、これが「コミットの履歴の上書き」に繋がります。

実際、force push前後で開発者的には同じcommitなのにコミット番号(8da33c0 とか)が異なります。

force push後に挙動がおかしくなった!戻さなきゃ!となった場合に元のコミット番号が参照できなくなってしまうので
「force push込みの差分なら分かるけど...??」状態になってしまいます。
自分だけが作業しているfeatureブランチでこれを起こしてしまったら自己責任で終わりですが、
他のメンバーが使用していたり本番反映で使用していたりするブランチに対して行ってしまうと一旦サービスを止めて修正して...みたいなことが起こりえます。

ブランチに対してforce pushを許容する・非許容にするというルール付けもできます。

もちろん、やらないとどうしようもない!みたいな時もあるかもなので「force pushは怖い」という表現にしていることも合わせて強調させてください!

なぜブランチ削除はプルリクエストを作成後が良いのか

他の手段から消すと復元できないからです。
git branch -d からの git push だとGitHubからの復元ができないので間違えたブランチを削除してしまったら終わりです。
また、GitHubの /branches からも削除ができ、削除した直後は復活できそうなボタンが出てきます。
しかしこれをリロードしてしまうと削除されたブランチは表示されないので誤って削除した直後以外の復活は難しいです。

ですがプルリクエストを作っておくと添付画像のようにブランチ削除後も「Restore branch」ボタンで復活できます。

自分のfeatureブランチだけでなくdevlopブランチを消したor消された経験は何度もあるので
心配であればマージする予定がなくてもPR作っておくと万が一に安心かなと思います。

ブランチに対して削除を許容する・非許容にするというルール付けもできます。

Discussion