結論
-
git init
直後のコミットは空コミットにしておいたほうがいいのでしている - EditorConfigでファイルフォーマットを統一するようにしている
- Gitフックでコミット先のブランチを間違えないようにしている
- GitHubなどのGitホスティングサービス側で特定ブランチのpushを受け付けないようにしている
はじめに
すべて個人の感想です
何か開発を行うとき、バージョン管理システムとしてGitを使うことが多いと思います。
しかし、Gitを使った開発を行っていると、以下のようなことが起きてしまうことがあります。
- 開発者のエディタ間の設定が異なっていてタブとスペースが混在する
- ブランチを切り替え忘れて本来コミットしてはいけない
main
ブランチなどにコミットしてしまう
これらを防ぐよう、個人的に意識しているGitリポジトリの初期設定をまとめようと思います。
対象読者
- Git操作(
add
,commit
,push
,rebase
など)が分かる人 - チーム開発を行うときに意図しない変更を防ぎたい人
- Gitを活用したい人
執筆にあたっての実行環境
- OS: macOS 15.1.1 24B91 arm64
- Gitバージョン: 2.39.5 (Apple Git-154)
1. 最初のコミットは空コミットにする
git init
を実行した直後に作成するコミットはルートコミットと呼ばれる特殊なコミットです。
ルートコミットはコミット情報に親コミット(1つ前のコミット情報)を持たないため、rebaseなどの操作が行いにくいです。
そこで--allow-empty
オプションを付け、空のコミットを作ることでrebaseなどの操作を行いやすくします。
$ git init # リポジトリの作成
$ git commit -m "feat: create new repository" --allow-empty # 空コミットの作成
[main (root-commit) 85a3ead] feat: create new repository
$ git commit -m "chore: 2nd commit" --allow-empty # 2つ目のコミット
[main 0b34365] chore: 2nd commit
$ git log --pretty=raw # コミット全体の情報を表示
commit 0b343658475dd01cb9d15a28d98951a33adeb3be
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent 85a3eadeb80e442f749bbbd2bfdd4e527258eab5 # parentがある
author Mitsu <tech.mitsu.yuki@gmail.com> 1740490213 +0900
committer Mitsu <tech.mitsu.yuki@gmail.com> 1740490213 +0900
chore: 2nd commit
commit 85a3eadeb80e442f749bbbd2bfdd4e527258eab5
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # parentがない
author Mitsu <tech.mitsu.yuki@gmail.com> 1740490205 +0900
committer Mitsu <tech.mitsu.yuki@gmail.com> 1740490205 +0900
feat: create new repository
個人的にはまだ初回でrebaseを使うような場面には出会ったことは無いです。
ですが、いつ出会うのかわからないのでやるようにはしています。
2. README.md
をコミットするよりも先に.editorconfig
を設定する
Gitを使うということは何かしらのテキストファイルを管理することになると思います。言ってしまえばREADME.md
もテキストファイルです。
これらのテキストファイルのタブインデントといったフォーマットを、エディタに依らず設定できるものがEditorConfigです。
EditorConfigに対応しているエディタや編集環境は非常に多いです。
エディタ単体で対応しているものでいうとVimやNeovim、IntelliJ IDEAなどのJetBrains系。GitHubやGitLabなどのGitホスティングサービス側のオンラインエディタで対応していたりします。
別途プラグインが必要にはなりますが、EmacsやSublime Text、VSCode、Notepad++などが対応しています。
これだけ多くのエディタがサポートしている、ファイルフォーマット設定を行わないわけにはいかないですね。
設定ファイルの記述も簡単なのでサクッと書いちゃいましょう。
以下は私が作成したGo言語プロジェクト向けの.editorconfig
です。
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[*.go]
indent_style = tab
indent_size = 4
[*.md]
trim_trailing_whitespace = false
これを導入することで以下のようなファイルフォーマット設定が有効になります
- 改行コードはLF
- ファイル末尾の空行を許可
- 文字コードはUTF-8
- インデントは基本的にスペース幅が2のスペースインデント
- goファイルのインデントはスペース幅が4のタブインデント
- Markdownファイルは行末スペースを許可
これでセーブした途端にエディタのフォーマッターが実行されて、インデントが狂うことや、Markdownファイルの末尾スペースが削除されて改行が消滅する悲劇から救われますね。
3. Gitフックを使って大事なブランチへの誤コミットを防ぐ
作業に没頭しているとブランチを切り替え忘れ、main
などの大事なブランチに誤ってコミットしてしまうことがあると思います。これを防ぐ方法の一つがGitフックです。
Gitフックとは、Gitの特定のアクションが発生したときにカスタムスクリプトを実行する機能です。
このカスタムスクリプトはgit init
時にリポジトリの.git/hooks
に作成されます。
初期状態では.git/hooks
以下にサンプルスクリプトが作成されています。
git init
時に作成されますが、ファイル名の末尾が.sample
になっているとカスタムスクリプトは実行されません。
実際に使うときは.sample
を除去したファイル名にします。
$ ls .git/hooks
applypatch-msg.sample pre-push.sample
commit-msg.sample pre-rebase.sample
fsmonitor-watchman.sample pre-receive.sample
post-update.sample prepare-commit-msg.sample
pre-applypatch.sample push-to-checkout.sample
pre-commit.sample update.sample
pre-merge-commit.sample
例えばgit push
を行う前にpre-push
というシェルスクリプトが実行されるような仕組みです。
このカスタムスクリプトの中に、コミットする前に実行するpre-commit.sample
とあります。
こちらに簡単なシェルスクリプトを作成して、特定のブランチ名のときはコミットできないようなシェルスクリプトを作成しましょう。
#/usr/bin/env bash
current_branch=$(git rev-parse --abbrev-ref HEAD)
# コミットを禁止するブランチ名を指定する
declare -a forbidden_branches=("release" "main")
for branch in "${forbidden_branches[@]}"; do
if [ "${current_branch}" = "${branch}" ]; then
echo "❌ Error: You are trying to commit directly to ${branch}!"
echo "Please create a new branch and commit there instead. 🌟"
exit 1
fi
done
作成したら.git/hooks/pre-commit
に実行権限を付けましょう。
$ chmod u+x .git/hooks/pre-commit
main
ブランチにコミットしてみるとpre-commit
が実行され、コミットが作られていないことがわかります。
$ git commit -m "wrong commit" --allow-empty
❌ Error: You are trying to commit directly to main!
Please create a new branch and commit there instead. 🌟
$ git log --oneline
0b34365 (HEAD -> main) chore: 2nd commit
85a3ead feat: create new repository
GitフックをGitで管理して共有する
Gitフックの便利さが伝わったと思います。
しかし作成したGitフックのカスタムスクリプトは.git
ディレクトリ以下にあるため、そのままではGitで管理できず、プロジェクトとしての共有もできません。
そこでGitで管理できる別のフォルダにカスタムスクリプトを作成し、Gitフックが保存されいてるディレクトリ設定を変更します。
カスタムスクリプトを格納するディレクトリを作る
場所はどこでも良いのですが、個人的には.githooks
が気に入っています
$ mkdir .githooks
$ vim .githooks/pre-commit # pre-commitを編集
$ chmod u+x .githooks/pre-commit # 実行権限付与を忘れずに
$ tree
.
└── .githooks
└── pre-commit
これで作成したカスタムスクリプトをGitで管理することができました。
カスタムスクリプトを共有する
実行するGitフックのカスタムスクリプトが置いてあるパスは、デフォルトでは.git/hooks
を使用します。
これはGitの設定にあるcore.hooksPath
より変更が可能です。
先ほど作成した.githooks
を指定する場合は以下のコマンドを実行します。
$ git config --local core.hooksPath .githooks # Gitフックの参照先パスを.githooksにする
$ git config -l --local
(省略)
core.hooksPath=.githooks # 参照先が.githooksになっている
こうすることでGitフックのカスタムスクリプトをGitで管理しつつ、プロジェクトで共有することができるようになりました。
あとはREADME.md
などに「git config --local core.hooksPath .githooks
を実行しておいてね」とか記述しておけば良いと思います。
4. GitHubで保護ブランチを設定する
Gitフックで大事なブランチへの誤コミットを防ぐ仕組みを作っていても、Gitフックの設定をしていない人がいたら元も子もありません。
そこで、間違って大事なブランチへの誤コミットされた上にpushされても、GitHubからpushを受け入れないようにしましょう。
-
設定したいGitHubのリポジトリに移動して「Settings」を選択します
-
サイドバーの「Code and automation」から「Branches」を選択します
-
「Branch name pattern」に保護したいブランチ名を入力します
これにて大事なブランチにpushされてしまい悲劇から回避できます。
まとめ
個人的に意識しているGitリポジトリの初期設定について説明しました。
作業ミスや不注意による事故を仕組みで減らせるなら減らしていきたいものですn。
誰かの助けになれば幸いです。
参考にしたページ