Gitブランチフロー規約

フューチャー株式会社

本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。

ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。

また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。

1 はじめに

本規約はGitブランチ管理の標準的な運用ルールをまとめている。以下の想定で作成されているため留意すること。

2 免責事項

::: warning 有志で作成したドキュメントである

:::

3 基本方針

一般的なGitブランチ運用のプラクティスに従い、本規約も以下の方針に則る。

4 ブランチの種類

本規約で想定する、ブランチの種類とその役割を説明する。

ブランチ名称 役割 ライフサイクル 派生元ブランチ 命名規則 直プッシュ
main プロダクション環境との同期 永続的 - main 固定 ❌️
feature 特定機能の追加/変更 短命 maindevelop feature/${チケット番号}: 詳細はfeatureブランチ を参照 ✅️※1
develop 開発の大元 永続的 main develop 固定。複数必要な場合は develop2 と連番にする ❌️
release リリース作業用途 短命 develop release/${yyyymmdd}release/${リリースバージョン} など ❌️
hotfix mainブランチに対する即時修正 短命 main hotfix/${チケット番号}: featureブランチに準じる ✅️
topic 複数人での機能開発用途 短命 feature topic/${チケット番号}: featureブランチに準じる ✅️

※1: topicブランチを利用する場合は、派生させたfeatureブランチへの直プッシュはNGとなる

4.1 mainブランチ

Gitリポジトリを新規作成するとデフォルトで作成されるブランチ。masterからmainに改名された経緯を持つ1

マージ毎にプロダクション環境へデプロイし同期を取る。

4.2 featureブランチ

機能追加や変更を行うブランチで、主な特徴は以下である。

feature branch

以下の命名に従う。

# OK(課題管理システムの課題番号をブランチ名に利用)
feature/#12345

# OK(GitHub Issue や JIRA や Backlog のプロジェクトIDをブランチ名に利用)
feature/<PROJECTID>-9403

# NG(プレフィックスが無い)
fixtypo

4.3 developブランチ

開発の中心となるブランチである。

develop branch

4.4 releaseブランチ

リリースするために使用するブランチで、主な特徴は以下である。

release branch

4.5 hotfixブランチ

本番リリースに対して迅速にパッチを当てて修正する場合に使用するブランチで、主な特徴は以下である。

hotfix branch

4.6 topicブランチ

featureブランチで実現する機能を複数人で開発する場合に使用するブランチである。

topic branch

5 ブランチ戦略の選定

ブランチ戦略は以下の方針で選定する。

有名なブランチ戦略として以下がある。

本規約で推奨するブランチ戦略は次の2パターンであり、これをベースとして選択する。

名称 利用ブランチ デフォルトブランチ リリース作業ブランチ 備考
Lite GitLab Flow
※1
main
develop
feature
topic
hotfix
develop develop ・GitLab Flowからreleaseブランチを除いたパターン
・リリース作業時にdevelopマージを止められる場合に利用する
GitLab Flow main
develop
release
feature
topic
hotfix
※2
develop release ・リリース作業と開発作業が並行して行う必要があるか、
断面を指定して複数テスト環境にデプロイしたい場合に利用する

6 ブランチ戦略とデプロイメント環境

各ブランチ戦略ごとに、デプロイメント環境に対応するブランチを整理する。プロダクション環境リリース前には、mainブランチでタグを打つこととする。

名称 開発環境 ステージング環境 プロダクション環境 備考
Lite GitLab Flow develop develop main ・開発環境へはdevelopマージをトリガーにCI/CDでデプロイを推奨する
・開発環境へのデプロイ漏れを防ぐため定期的にCI/CDでdevelop断面をリリースすることを推奨する
・動作確認など理由がある場合はfeatureブランチから直接開発環境へのデプロイも許容する
・ステージング環境は日次など定期的なCI/CDによるデプロイを推奨する
GitLab Flow develop release main ・開発環境へはdevelopマージをトリガーにCI/CDでデプロイを推奨する
・検証期間が長引きそうな場合は、PRレビュー承認後にfeatureブランチから開発環境へのデプロイを許容する

7 ブランチ戦略の拡張

次のような要件があった場合には、ベースとなるブランチ戦略を拡張する必要がある。

  1. developブランチを複数作成する場合
  2. 過去バージョンをサポートする場合

7.1 1. developブランチを複数作成する場合

multi develop branch

日々のエンハンス開発と並行して、数カ月後に大型リリースを行いたい場合がある。このときは複数リリースバージョンを並行して開発するため、 developdevelop2 といった複数のdevelopブランチを作る必要がある。

概要:

develop2 同期の注意点:

release multi develop branch

7.1.1 develop2のリリース手順

  1. developからdevelop2へマージコミットする(2でコンフリクトが起こらないよう、前準備の意味合いで実施する。)
  2. develop2からdevelopにマージを行い、その後は通常のリリースフローに従う
  3. 問題なくリリースが完了し次第、develop2を削除する

developからdevelop2へマージ後、develop2mainブランチに反映させる手順も考えられるが、develop2からdevelopへのマージとすると以下のメリットがある。

7.2 2. 過去バージョンをサポートする場合

multi version branch

(社内外の)ライブラリでインターフェースの大型改善や仕様変更を受けて、メジャーバージョンを1→2に上げることがる。この時に過去バージョンもサポートする必要があると、バージョン別にsupportブランチを作成する。

概要:

8 マージ戦略の選定

マージ戦略とは、複数のブランチ間で生じた変更の取り込み方針を指す。

具体的には次の3ケースそれぞれで、「マージコミット」「リベース」「スカッシュマージ」のどれを採用するか判断する。

  1. developブランチからfeatureブランチへ変更を取り込む
  2. featureブランチからdevelopブランチへ変更を取り込む
  3. 永続ブランチ間で変更を取り込む

以下に影響を与えるため、Gitの利用開始前に決めチームで統制を図ることが重要である。

8.1 1. developブランチからfeatureブランチへ変更を取り込む

featureブランチでの作業中に、developブランチが更新された場合、品質保証の観点でdevelopブランチの変更をfeatureブランチに取り込んだ上で、テストなどの検証作業を行う必要がある。

developブランチの変更をfeatureブランチに取り込む方法には、下表の2つの方法が存在する。

機能ブランチに対して開発ブランチの変更を取り込む方法は「マージ」「リベース」2つの方法が考えられる。

1. マージコミット 2. リベース
マージ リベース
get fetch & git merge(≒ git pull)。マージコミットが作成される get fetch & git rebase(≒ git pull --rebase)。最新の開発ブランチの先頭から新たにコミットを作りなされ、マージコミットは作成されない

本規約の推奨は「2. リベース」である。

理由は次の通り。

この選択にあたり、以下の設定を行う。

  1. git pull 時の挙動がリベースになるよう git config pull.rebase true を実行する
  2. developブランチの変更を取り込む場合、同じコンフリクトの解消を何度も求められることを解消するため、git config rerere.enabled true を実行する

マージによる変更の取り込みが既存のブランチを変更しないのに対し、リベースは全く新しい(元のコミットIDとは別のコミットIDで)コミットを作成するため、次の1点に注意すること。

  1. リモートにプッシュ済のブランチがあり、developブランチからさらに変更をリベースで取り込んだ場合、強制プッシュ(Force Push)が必要になる

::: tip 強制プッシュでレビューコメントは消えるのか?

強制プッシュすることにより、レビューコメントが消えてしまわないかという懸念を聞くことがある。2024年7月に実施した調査結果では問題なかった。

サービス a.履歴保持 b.行単位の紐づけ(該当行の変更なし) c.行単位の紐づけ(該当行の変更あり)
GitHub 残る 残る 消える
GitLab 残る 残る 消える

:::

8.1.1 プルリクエスト作成前にアップストリームをプルする

featureブランチの開発が終わり、プルリクエストを作成する際には、改めてアップストリーム(developブランチ)の変更をfeatureブランチに取り込み、差分が無いことを確認すべきである。

理由は次の通り。

8.1.2 プルリクエストのレビュー依頼までにどこまでテストしておくべきか

本規約で推奨する Lite GitLab Flow GitLab Flow ともに、開発環境へはdevelopマージをトリガーにCI/CDでデプロイを推奨している。

そのため、プルリクエスト作成時点では開発環境(≒AWSなどクラウド環境の想定)へのデプロイ+動作検証は不要である。

ローカルでの開発のみで品質担保が難しく手戻りが多い場合は、サンドボックス環境や開発環境にfeatureブランチからデプロイして動作検証する作業が必要になる。開発環境を共有する場合は、デプロイタイミングの制御がチーム内で必要になるため、運用ルールを検討する必要がある。

8.1.3 Terraformはレビュー依頼時点でどこまで確認しておくべきか

Terraformはplanが成功しても、applyが失敗することは多々あり(サブネットが足りなかった、force_destory=trueを明示的な設定が必要だったなど)、レビューでの見極めは難しいことが多い。そのため、applyをどのタイミングで実施するかがチームの生産性の鍵となる。

大別すると以下の3方式が存在する

  1. マージ後にapply
  2. Approve後にapply
  3. レビュー依頼前にapply

それぞれの特徴を下表にまとめる。

観点 ①マージ後にapply ②Approve後にapply ③レビュー依頼前にapply
説明 developブランチにマージ後にapply。アプリコードと同じメンタルモデルを共有可能 レビュアー承認後にapply。featureブランチからapplyするため、あるべき姿からは外れる レビュー依頼前にapplyで成功したことを確認する方式
developブランチ品質 ❌️一時的にapplyが失敗するコードが混入するリスク ✅️apply可能なコードのみに保つことができる ✅️apply可能なコードのみに保つことができる
レビュー負荷 ❌️applyの成否は不明なので心理的負荷あり ❌️applyの成否は不明なので心理的負荷あり ✅️applyが成功している前提で対応可能。apply結果をコンソールからも確認可能
apply失敗時のコスト ❌️再度PRを作る必要があり手間 ✅️同一PRを流用できる ✅️apply成功後にPR作成が可能
PRのトレーサビリティ ❌️PRが割れると面倒 ✅️同一PRである ✅️同一PRである
環境のバッティング ✅️ない ⚠️Approveからdevelopマージまでの間に、他メンバーの作業と重複するとややこしい ❌️作業調整が必要
ガバナンス ✅️applyをCIのみに絞るなど自動化と相性が良い ⚠️レビュアー承認後のコードのみapply対象とできる ❌️ノーレビューのインフラ変更を適用するため、初学者が多いチームには適用が難しい
結論 applyの成功率が高く維持できる場合に有効 applyの成功率が低い場合に有効 少数精鋭の場合に採用可能な、上級者向けの方式

本規約の推奨は以下。

8.2 2. featureブランチからdevelopブランチへ変更を取り込む

プルリクエスト(以下、PR)を経由して、開発が完了したfeatureブランチをメインのdevelopブランチに取り込むためには、GitHub(GitLab)上でPRを経由する運用を行う。

developブランチにfeatureブランチの変更を取り込む方法は下表のように3パターン存在する。

1.マージコミット 2.リベース 3.スカッシュマージ
名称 Create a merge commit Rebase and merge Squash and merge
流れ Merge Commit Rebase and Merge Squash and Merge
説明 git merge --no-ff で変更を取り込む featureブランチを最新のdevelopブランチにリベースし、git merge --ff で変更を取り込む git merge --squash で変更を取り込む
特徴 developブランチにマージコミットが作成される マージコミットは作成されず、履歴が一直線になる featureブランチで行った変更YとZを1つにまとめたコミットがdevelopブランチに作成される

::: tip GitLabを利用する場合

GitLabでも開発ブランチに機能ブランチの変更を取り込む方法は3種類ある。

ただし、マージリクエスト上のオプションによってコミット履歴が変わる点が注意である。

1. Merge commit 2. Merge commit with semi-linear history 3. Fast-forward merge
流れ Merge commit with squash commits 省略 省略
説明 GitHubにおける Create a merge commit と同様のマージ方法 Merge commit と同じコマンドを使用して、機能ブランチの変更を取り込む方法 GitHubにおける Rebase and merge と同様のマージ方法
注意 Squash commits を選択してマージした場合、squash commitmerge commit の2つのコミットが作成される ソースブランチがターゲットブランチより古い場合はリベースしないとマージできない。 マージリクエスト上で Squash commits を選択してマージした場合、GitHubにおける Squash and merge と同様のマージ方法になる(※補足1)

(※補足1)マージ方法で Merge commit を選択して、マージリクエスト上で Squash commits オプションを選択してマージした場合は以下と同義である

git checkout `git merge-base feature/A develop`
git merge --squash feature/A
SOURCE_SHA=`git rev-parse HEAD`
git checkout develop
git merge --no-ff $SOURCE_SHA

:::

本規約の推奨は、「スカッシュマージ」による方法である。

理由は次の通り。

「スカッシュマージ」を行うと、変更元のfeatureブランチのコミットをまとめたコミットが新たに作成されるめ、元のfeatureブランチを再利用しPRを作成するとコンフリクトが発生する。そのためマージ後はリモート/ローカルの双方で速やかにfeatureブランチを削除させるため、以下の設定を加える。

「スカッシュマージ」による変更の取り込みを行う場合、次の2点に注意すること。

  1. 部分的なコミットの取り消しができない
  2. Authorが失われる

8.2.1 マージはだれが行うべきか

プリリクエストの承認(Approve)をもらった後、マージはレビュアー/レビュイーのどちらが行うべきか議論になる場合がある。

観点 レビュアー派 レビュイー派
説明 開発者の責務が、developブランチにマージするまでという役割分担の場合に有効 各開発者がその機能のリリースについて責任を負うモデルの場合に有効
生産性 ⚠️レビュアーがブロッキングになりがち ✅️高い。コメントはあるがApproveしたので、適時対応してマージして、といった運用が可能
統制 ✅️レビュアーが管理しやすい ✅️メンバーの自主性に依存
要求スキル ✅️低い。中央で統制を行いやすい ⚠️開発メンバーの練度が求められる

上記にあるように、そのプルリクエストで実装した機能を、本番環境にデリバリーする責務をどちらに持たせるかという観点で、意思決定することが多い。

本規約の推奨は以下。

8.3 3. 永続ブランチ間で変更を取り込む

永続ブランチ同士の変更を取り込むケースとして、develop ブランチを main ブランチや releaseブランチにマージするといった場合がある。

ブランチ間の同期が取れないため「リベース」「スカッシュマージ」は選択できないため、「マージコミット」を採用する。

9 ブランチ運用アンチパターン

ブランチ運用でよく課題に上がるパターンとその対応を紹介する。

9.1 追い抜きリリース

以下のような状況とする。

同一ファイルを複数

よく陥りがちな対策としては次の2点が考えられる。

  1. issue-312をリバートする
  2. issue-394のコミットのみをcherry pick してmainブランチにマージする

1のリバートはGitHubの機能で提供されていることもあり簡単に行えるが、手戻りであることは間違いないし、コミットの履歴が汚れるため、保守運用の視点ではマイナスである。2のcherry pickは操作、管理ともに煩雑でミスが出やすいという課題がある。

処方箋だが、前提条件によって別の対応策が考えられる。

  1. issue-312のマージがおかしいとするケース
  2. issue-394のマージがおかしいとするケース

2の例を以下に図示する

hotfixで追い抜き

10 ブランチ命名規則

ブランチ名の命名規則は、ブランチの種類 章に従うこと。

11 タグ規則

Gitにはタグ機能があり、リリースポイントとしてタグを作成する運用とする。

これにより、リリースしたアプリケーションやライブラリに何か不具合があれば、切り戻しや原因追求が容易になる利点がある。

11.1 タグの運用ルール

GitHub画面でbackend/v1.6.0のタグを作成する

何かしらの理由で、コマンドラインからタグを作成する必要がある場合は、以下に注意する。画面経由・コマンドライン経由でのタグ作成は混ぜないようにし、運用手順は統一する。

# OK(注釈付きタグを利用する)
$ git tag "v1.0.4" -m "v1.0.4 🐛Fix item api log"

# NG(軽量タグは利用しない)
$ git tag "v1.0.4"

::: warning タグが迷子になる?

タグはmainなど永続ブランチで作成する必要がある。例えばfeatureブランチでタグを作成し、git push origin {tag_name} でリモートにプッシュしたとしても、rebase でその紐付けが消えてしまう。なぜなら、タグはコミットのハッシュに付与されるラベルであり、rebase でコミットのハッシュが変わると、どのコミットに対するタグなのか分からなくなってしまうからである。 :::

11.2 タグの命名規則

命名に従うと、次のようなコマンドで絞り込みで表示できる。

$ git tag -l --sort=-version:refname "frontend/v*"
frontend/v2.0.0
frontend/v1.3.0
frontend/v1.2.0
frontend/v1.1.0
...

また、Gitクライアントによっては / を使うことでフォルダのように階層表示ができるため、プレフィックスの区切り文字は - ハイフンではなく、スラッシュとする。

11.3 タグメッセージの規則

create new tag

何かしらの理由で、コマンドラインからタグを作成する必要がある場合は、GitHub利用時の規則に合わせて次のように作成する。

入力例:

# OK
$ git tag -a backend/v1.8.0 -m "backend/v1.8.0"
$ git tag -a backend/v1.9.0 -m "backend/v1.9.0 🚀Release with frontend-v3.0.1"
$ git tag -a backend/v2.0.0 -m "backend/v2.0.0 ✨Android版アプリリリース対応"

# NG
$ git tag -a backend/v3.0.0 -m "🚀Release version v2.0.0"

11.4 バージョンアップ規則

12 ラベル規則

IssueやPRを分類することができるラベルについての利用は自由とする。

PRに適切なラベルを設定し、 自動生成リリースノート - GitHub Docs に記載があるように .github/release.yml への設定を行うことで、リリースノートの生成をラベル単位にグルーピングできる。

PRを後で探しやすくするための検索キーとしての位置づけと、リリースノート自動生成という観点でラベルを準備すること。

13 コミットメッセージ規則

Gitのコミットメッセージは原則自由とする。理由は以下である。

チーム規模や特性によっては、Gitのコミットメッセージをルール化する方ことにより、メリットがある場合は Conventional Commits をベースとした以下の規約を推奨する。

::: tip Conventional Commitsの勧め Gitのコミットメッセージにの書式についてルール化することで、コミットの目的がわかりやすくなる、履歴からのトラッキングの容易になる利点がある。

本規約のコミットメッセージの書式としては、Conventional Commitsをベースとした規約としている。

以下の形式でコミットメッセージを記載することとする。

<type>: <subject> <gitmoji>

コミットメッセージは type、subject、gitmojiの最大3つの要素から構成され、それぞれは後述する書式に従うものとする。 この中でも、type、subjectについては必須とし、ほかの要素についてはプロジェクトの運用にしたがい任意とする。

13.1 type

typeについては必須の要素となり、以下のいずれかを選択するものとする。

type 説明
feat 新機能の追加
fix バグの修正
docs ドキュメンテーションの更新
refactor リファクタリング

13.2 subject

subjectについては必須の要素となり、変更内容を簡潔に記載するものとする。 issue idについては、PRから参照する運用を想定し、コミットメッセージの必須要素とはしないこととする。

13.3 gitmoji

gitmojiについては任意の要素となり、変更内容を視認しやすい絵文字の使用を可能とする。

変更内容と選択される絵文字の対応については厳密とせず、開発者が任意に選択するものとする。

type(feat, fix, docs, refactorなど)に基づく、選択例を以下に示す。

 ==== Emojis ====
 :ambulance:  🚑致命的なバグ修正(fix)
 :bug:  🐛バグ修正(fix)
 :+1: 👍機能改善・機能修正(fix)
 :cop: 👮セキュリティ関連の修正(fix)
 :art: 🎨レイアウト関連の修正(fix)
 :green_heart: 💚テストやCIの修正・改善(fix)
 :wrench: 🔧設定ファイルの修正(fix)
 :building_construction: 🏗️アーキテクチャの変更(fix)
 :tada: 🎉大きな機能追加(feat)
 :sparkles: ✨部分的な機能追加(feat)
 :up:   🆙依存パッケージ等のアップデート(feat)
 :memo: 📝ドキュメント修正(docs)
 :bulb: 💡ソースコードへのコメント追加や修正(docs)
 :lipstick: 💄Lintエラーの修正やコードスタイルの修正(refactor)
 :recycle: ♻️リファクタリング(refactor)
 :fire: 🔥コードやファイルの削除(refactor)
 :rocket: 🚀パフォーマンス改善(refactor)

13.4 コミットメッセージ例

上記のルールに従った、コミットメッセージのサンプルは以下のようなものとなる。 以下のようなコミットをルールとすることで、変更内容を視覚的に把握しやすくなる利点がある。

feat: カレンダー機能の追加 🎉
fix: メモリリークの修正 🚑
docs: デプロイフローをドキュメント化 📝
refactor: Lintエラーの修正 💄

:::

14 git config推奨設定

git config の推奨設定を紹介する。特にGitワークフローの設定が重要である。

# 基礎
git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"

# プロキシ設定(存在する場合)
git config --global http.proxy http://id:password@proxy.example.co.jp:8000/
git config --global https.proxy http://id:password@proxy.example.co.jp:8000/

# プロキシが独自の証明書を持っている場合は、git config http.sslVerify false ではなく、証明書を設定する
git config --global http.sslCAInfo ~/custom_ca_sha2.cer

# Gitワークフロー
git config --global pull.rebase true
git config --global rerere.enabled true
git config --global fetch.prune true

# エイリアス(メンバーそれぞれで別のエイリアスを登録されると、チャットなどのトラブルシュート時に混乱をきすため、ベーシックなものはチームで統一して、認識齟齬を減らす目的で設定を推奨する)
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch

::: tip git workflowの補足説明

15 git-secrets

git-secretsを用いることで、ユーザーパスワードや AWS アクセスキーなどの機密情報が含まれる可能性のあるコードなどをGit リポジトリに追加されないようにできる。

本規約の推奨は以下。

16 コミットフックでテスト実行は行わない

git hooks を用いて、コミットやプッシュ時に単体テスト実行などのカスタム処理を追加することができる。これを用いると、ローカルでの動作検証などを未実施な状態でレビュー依頼をしてしまうといった状況を未然に防ぎ、開発フローを強制的に適用することができる。

本規約の推奨と理由は以下。

::: tip git hooksで何を行うべきか テスト、コード生成、リンターなど、実行時間が長いものは行うべきではない。

実行時間が短いフォーマットであれば、git hooksで実行させると便利なことが多く(CIで違反に気づいて対応する手戻りが減るためである)、必要に応じて導入しても良い。 :::

17 .gitattributes

17.1 eol

チーム開発において開発環境がWindows/Macなど複数存在することは少なくなく、また、Gitリポジトリ上の改行コードは統一した方が余計な差分が生じず扱いやすくなる。このときよく用いるのが、 core.autocrlf という設定である。

名称 設定値 チェックアウト時の挙動 コミット時の挙動
core.autocrlf true 改行コードをCRLFに変換 改行コードをLFに変換
input 何もしない 改行コードをLFに変換
false 何もしない 何もしない

特にWindowsでの開発者の作業ミスを防ぐため、 git config --global core.autocrlf input のような設定を行うチームも多い。

しかし、上記の設定漏れや手順が増えてしまうため、本規約では .gitattributes での対応を推奨する。

.gitattributes というファイルをGitリポジトリのルートにコミットしておけば、そのGitリポジトリを使う全員で改行コードの扱いをLFに統一できる。

sh .gitattributes * text=auto eol=lf

通常、改行コードやインデントの設定はEditorConfigで行うことが多く、 .gitattributes の設定とは重複する。しかし、環境構築ミスなど何らかのトラブルで動作しなかった場合に改行コードミスで特にジュニアクラスのメンバーが困る状況もゼロとは言えないため、本規約では .gitattributes も作成しておくことを推奨する。

::: warning 特定のファイルのみCRLFでコミットしたい テスト目的であるファイルだけCRLFで読み込ませたいとする。さきほどの .gitattributes の設定ではチェックアウト時に強制的にLFに変換されてしまうため、CRLFのファイルのみ個別で改行コードを指定する必要がある。例えば、testdata/eol配下のCSVをCRLFで扱いたい場合は、以下となる。

```sh .gitattributes * text=auto eol=lf

18 個別で指定

testdata/eol/*.csv text eol=crlf


前の行に書いた設定は、後ろの行に書いた設定によって上書きされるため、記載順は「全体に適用する原則」→「個別設定」となるように注意する。

この指定がちゃんと効いているか確認する場合は、 `git check-attr` コマンドを用いると良い。以下のように eolがcrlfで設定されたことが分かる。

```sh
$ git check-attr -a testdata/eol/input1.csv
testdata/eol/input1.cs: text: set
testdata/eol/input1.cs: eol: crlf

参考:

:::

18.1 linguist-generated

自動生成で変更が発生し、かつ大量の変更が頻繁に発生する場合には、レビュワーが毎回レビューをすることは効率的でない。

.gitattributeslinguist-generated=true の設定を行うことで、差分をデフォルトで表示させず、プルリクエストの可視性を向上させることができる。

sh .gitattributes # 自動生成されたHTMLファイルの差分を無視する /path/to/generated/*.html linguist-generated=true

上記の設定で /path/to/generated/main.html をコミットすると、差分が以下のように非表示となる(Load diffをクリックすることで差分表示は可能)。

プルリクエストのFile changedでmain.htmlの差分がLoad diffと表示

本規約の推奨は以下の通り。

::: tip 生成コードをレビュー対象としたい場合

GitHubでは、言語毎に生成ファイルと判定する処理があり、例えツールで作成されたファイルであっても、レビュー確認を必須としたい場合には、クリックする手間が増える分、逆に非効率になる。

例えば、Javaなど複数の言語では3行目までに Generated by the protocol buffer compiler. DO NOT EDIT! が含まれているとProtocol Bufferの生成コードとみなされる

もし、明示的に差分を表示させたい場合、linguist-generated=false を設定する必要がある。

sh .gitattributes # 以下はコード生成されたファイルだが、レビュー対象としたいためlinguist-generated=falseを設定し、差分を表示させる /path/to/generated/*.java linguist-generated=false

:::

参考:

19 .gitignore

Gitで管理したくないファイル名のルールを定義する.gitignoreファイルも入れる。ウェブフロントエンドであれば新規プロジェクトを作成すると大抵作成されるのでそれを登録すれば良いが、もしない場合、あるいは複数の言語を使っている場合などはGitHubが提供するテンプレートを元に作成すると良い。GlobalフォルダにはWindows/macOSのOS固有設定や、エディタ設定などもある。

環境設定を.envで行うのが一般的になってきているが、.env.local.env.dev.localといった.localがついたファイルはクレデンシャルなどの機微な情報を扱うファイルとして定着しているため、 *.localも追加すると良い。

20 個人用のファイルをGit管理対象外とする

.gitignore を用いると、チームでGit対象外とするファイルを一律で設定できる。

一方で、動作確認用のちょっとしたスクリプトなどで以下の要件が出てくることがある。

上記の場合は、.git/info/exclude を利用することを推奨する。

参考:

21 Pull Request / Merge Request テンプレート

GitHubやGitLabでは、プルリクエスト作成時のテンプレートを作ることができる。チームでプルリクエストで書いてほしいことを明示的にすることで、レビュー効率の向上や障害調査に役立てることができる。

GitHubでは .github/PULL_REQUEST_TEMPLATE.md に記載する。(GitLabでは .gitlab/merge_request_templates/{your_template}.md を配置する。)

テンプレートの例を以下にあげる。

## チケットURL

## 特に見てほしいレビューポイント

## 残課題(別チケットで対応予定の内容、別プルリクエストで対応予定の内容)

## 動作確認内容(画面キャプチャなど)

## セルフチェックリスト

- [ ] 開発規約(DEVELOPMENT.md) を確認した
- [ ] Files changed を開き、変更内容を確認した
- [ ] コードの変更に伴い、同期必要な設計ドキュメントを更新した
- [ ] 今回のPRでは未対応の残課題があればIssueに起票した

22 GitHub推奨設定

業務利用でのチーム開発を想定しており、リポジトリは以下の条件を満たす前提とする。

22.1 General

Category Item Value Memo
General Require contributors to sign off on web-based commits チェックなし 著作権・ライセンス承諾の場合に用いるが、業務アプリ開発では不要
Default branch develop
Pull Requests Allow merge commits ✅️ main <- developなどのマージ時に必要
Allow squash merging ✅️ develop <- feature はSquash mergeを推奨
Allow rebase merging - 利用しないため、チェックを外す
Allow suggest updating pull request branches ✅️ Pull Request作成後、ベースブランチが更新された場合、ソースブランチの更新を提案してくれる
Automatically delete head branches ✅️ マージ後にfeature branchを削除するため有効にする
Pushes Limit how many branches and tags can be updated in a single push 5 git push origin –mirrorで誤ってリモートブランチを破壊しないようにする。推奨値の5を設定する

22.2 Access

Category Item Value Memo
Collaborators and teams Choose a role 任意の権限 ※後述

22.3 Code and automation

22.3.1 Branches

Branch protection rules にdevelop, mainなど永続的なブランチに保護設定を追加する。

Category Item Value Memo
Protect matching branches Require a pull request before merging ✅️ プルリクエストを必須とする
Require approvals ✅️ レビューを必須とする
Required number of approvals before merging 1 最低1名以上の承認を必須とする
Dismiss stale pull request approvals when new commits are pushed - レビュー承認後のPushで再承認を必要とするかだが、レビュー運用上に支障となることも多く、チェックを外す
Require status checks to pass before merging ✅️ CIの成功を条件とする
Require branches to be up to date before merging 任意 CIパイプラインのワークフロー名を指定
Require conversation resolution before merging - レビューコメントがすべて解決していることを条件とする。チェックを外す
Require signed commits ✅️ 署名付きコミットを必須化し、セキュアな設定にする
Require linear history ✅️/- mainブランチの場合はOFFとするが、developの場合はSquash mergeを求めるため有効にする
Do not allow bypassing the above settings ✅️ パイパスを許容しない

developブランチに対し「require linear history」を選択することを推奨することで、「Create a merge commit」が選択できないようにする。

また、意図しない方法でのマージを避けるためにブランチごとにマージ戦略を設定しておき、想定外のマージ戦略が選択された時に警告色を表示するというサードパーティ製のChrome拡張3も存在する。必要に応じて導入を検討する。

22.3.2 Tags

Category Item Value Memo
Protect tags v[0-9]+.[0-9]+.[0-9] セマンティックバージョニングに則ったタグのみ、削除を防ぐ

22.3.3 GitHub Actions

Category Item Value Memo
Actions permissions Allow asset-taskforce, and select non-asset-taskforce, actions and reusable workflows > Allow actions created by GitHub ✅️
Allow asset-taskforce, and select non-asset-taskforce, actions and reusable workflows > Allow actions Marketplace verified creators ✅️

22.3.4 Code security and analysis

Category Item Value Memo
Dependabot Dependabot alerts ✅️ 依存パッケージのアップデートを検知するため
Dependabot security updates ✅️
Dependabot version updates ✅️

23 GitLab推奨設定

24 ローカルでのGit操作

24.1 gitコマンド

# 変更作業
git checkout -b <branchname>
git add
git commit -a

# リモートブランチの変更を同期
git pull origin develop

# コンフリクト対応
git add <file1> <file2> ...
git commit -a

# リモートブランチへプッシュ(pullした際にリベースしているため、オプションは必須である)
git push origin HEAD --force-with-lease --force-if-includes

24.2 VS Code

利用頻度が高いとされるGitクライアントである、VS Code上でのGit操作を紹介する。

::: tip VSCode上でのGit操作の紹介

VSCode上でのGit操作は、サイドバーの “Source Control” から行うことができる。ほとんど全ての操作はコマンドパレットからも実行可能だが、説明は割愛する。

24.2.1 推奨する拡張機能

GUIでのGit操作にあたり、次の2つの拡張機能をインストールしておくと利便性が高い。業務上はほぼ必須と見て良い。

以降では、これらの拡張機能がインストールされていることを前提に説明を行う。

24.2.2 リポジトリのクローン (git clone)

  1. サイドバー > Explorer か Source Control > Clone Repository ボタンをクリック
  2. URLを入力すると、リポジトリをクローンできる
1 2
Clone1 Clone2

24.2.3 コミットグラフの表示

  1. SOURCE CONTROL パネル > 黒丸のグラフアイコン (View Git Graph (git log)) をクリック
  2. コミットグラフが表示される
1 2
Graph1 Graph2

白丸のグラフアイコン (Show Commit Graph) はGitLensのコミットグラフだが、冒頭の記述通り、Pro版でのみの提供となる。

24.2.4 リモートのフェッチ/プル (git fetch / git pull)

以下のいずれかの操作を実行すると、リモートリポジトリをフェッチできる。

a, bの手順両方を記載
Fetch1

なお、フェッチ後に以下のようなダイアログが表示される場合があるが、 “Yes” を選択すると、自動で定期的にフェッチを行う。

Fetch2

24.2.5 ブランチの作成/チェックアウト (git branch / git checkout)

以下のいずれかの操作を実行すると、ブランチを作成できる。

a b
Branch1 Branch2

24.2.6 ステージ/コミット/プッシュ (git add / git commit / git push)

  1. SOURCE CONTROL パネル > 変更ファイルの行 > +アイコン (Stage Changes) をクリックすると、対象ファイルをステージできる。(Changes > +アイコン (Stage All Changes) をクリックすると、すべての変更をステージする)
  2. 必要な変更をステージ後、 SOURCE CONTROL パネル内でコミットメッセージを入力し、 Commit ボタンをクリックすると、コミットを作成できる
1 2
Stage Commit

以下のa~cいずれかの操作を実行すると、作成したコミットをリモートリポジトリにプッシュできる。

a b c
push1 push2 push3

:::


  1. https://github.com/github/renaming↩︎

  2. https://docs.github.com/ja/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors↩︎

  3. https://zenn.dev/daku10/articles/github-merge-guardian↩︎