はじめに結論
.env.example
などに機密情報を載せたままGitHubにpush
してしまった人は、git
のcommit
履歴を git rebase
で改変して、GitHubに強制push
しよう!
この記事を読むと…
- GitHubに機密情報を
push
しちゃった人がその後すべきことがわかる -
git rebase
の練習ができる
私の場合の経緯
git rebase
の練習だけやってみたい人は、飛ばしていただいて問題ありません!
私と同じ状況に陥っている方や、セキュリティ意識を高めたい方は、ぜひご一読ください。
私は現在、プログラミング学習とポートフォリオ作成を兼ねて、Laravelを用いた基本的なCRUDアプリを個人開発中の身です。
今回は、開発の序盤も序盤。
ユーザ登録時のメール認証が動作しているかを試すために、Mailtrapというツールを使うことにしました。
.env.example
とは
Mailtrap接続のための情報は、.env
に入れる必要があります。
これを他の環境でもすぐに使えるように、 .env.example
を作成しました。
env.example
というのは、.env
に書くべき環境変数をまとめた、.env
のサンプルとなるファイルです。
環境構築時に、これをcp .env.example .env
という形でコピーして、必要事項を埋めるだけで、.env
が完成するので早いよ!というものです。
ただし、 機密情報は絶対に.env.example
には載せてはいけません。
通常、.env
は.gitignore
されており、git管理外となっているので、GitHubには上がりません。よってインターネット上に漏れることはありません。しかし、.env.example
は、いろんな環境で使ったり、他のメンバーと共有したりするために、git管理するのが前提のファイルです。
これに機密情報を載せてしまい、さらにGitHubリポジトリがPublic設定になっていると、とても危険です。GitHub 上を巡回している悪意あるクローラー、つまり情報漏洩を狙う自動巡回プログラムによって、その情報が取得され、アカウントを不正利用 されてしまう恐れがあります。
Mailtrapくらいなら大きな問題はないかもしれません。しかし、例えば AWS との接続情報が漏れていたりすると、マネーロンダリングなどにサーバやストレージを不正利用されてしまうかもしれません。そうすれば、多額の請求を受けるといったことになりかねません。
.env.example
で伏せるべき情報はパスワードだけではない
Mailtrapに登録する情報は、これだけあります。
MAIL_MAILER=smtp
MAIL_SCHEME=null
MAIL_HOST=
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tsl
MAIL_FROM_ADDRESS="sample@example.com"
MAIL_FROM_NAME="${APP_NAME}"
私は甘いことに、パスワードだけ伏せたら完璧!と思っていました。
しかし、知人エンジニアより指摘を受けました。
「アカウント名やサービス名、使ってるDBなども、一応隠しておくに越したことはない」 と。
なぜなら、他の情報と合わせて取得されると悪用されるリスクが高まるからです。
あくまでも、.env.example
は形式の参考であり、実値は書かない ということを覚えておきましょう。
私はやってしまいました。
思いっきりアカウント名も書いていました。
そのままGitHubにpushまでしてしまいました。
こうなると、たとえ今から.env.example
を編集してcommit
してpush
しても、コミット履歴に機密情報が残ったままになってしまいます。
では、これからどうすればいいのでしょうか。
機密情報をpush
しちゃった後にやること
GitHubのリポジトリをPrivateにする
GitHubの該当リポジトリのページから、setting
タブを開きます。
ページ下部にあるDanger Zone
の、Change repository visibility
に移動し、Change Visibility
ボタンからPrivate
に変更します。
このようにして、悪意あるクロールの対象からいち早く外れましょう。
私の場合は、最初からPrivateにしていたので少し安心でした。
開発中は、不特定多数への公開の必要がないなら、Privateにしておくに越したことはないです。
私は就職活動が始まるまではPrivateのままにしておこうと思っています。
機密情報を再発行する
これはリポジトリがPublicになっていた場合だけでよいかもしれません。
.env.example
に記入した情報はすべて漏れたものと考えて対処するのが安全です。
各サービスのAPIキーやパスワード、ユーザ名など、再発行できるものはすぐに取得しなおしましょう。
その上で、.env
にその値を設定します。
git rebase
でコミット履歴を書き換える
ここで満を持して登場するのがrebase
です。
過去のコミット履歴を改変することができる、使い方によっては危ないコマンドです。
このことからわかるように、 本番環境や、共同開発者がいる状況で気軽にやってはいけません。
あらゆる人の元でコンフリクト(競合)が発生して大変なことになります。
もし本番でrebase
で修正しなければならないような重大なミスをしてしまった場合は、速やかに周囲に報告して対象のブランチをpull
しないよう呼びかけ、リポジトリの公開設定をprivateにした後、以下の手順を行うことになるでしょう。
git rebase
の手順
いきなり本番でrebase
するのは怖いと思いますので、今回は練習用のリポジトリを作って試してみましょう。
私も知人にその形で教えてもらい、安心して実際の作業に取り組めました。
ではまず、練習用のディレクトリを作り、そこまで移動しましょう。
mkdir rebase-test
cd rebase-test
このディレクトリをgit管理できるようにしましょう。
git init
このディレクトリに、test.md
というテスト用のファイルを作成します。
まずはtest.md
に、「1行書いてadd、commit」を3回繰り返して、コミット履歴を作りましょう。
1 行目
git add -A
git commit -m "1行目のコミット"
1 行目
25 行目 //この行を追加。あえて間違った数字を入れます
git add -A
git commit -m "25行目のコミット" #ついでにコミットメッセージも間違えておきましょう。
1 行目
25 行目
3 行目 //この行を追加
git add -A
git commit -m "3行目のコミット"
これらを、GitHubにpush
しましょう。
GitHubで新しいリポジトリを作り、push an existing repository from the command line
にあるコードを貼り付けます。
git remote add origin https://github.com/GitHubアカウント名/rebase-test.git
git branch -M main
git push -u origin main
ここまでで、 「不適切なコミット履歴をGitHubにpush
してしまった…」という私のやらかしを再現できました。
では、 作成したコミット履歴をgit log
で確認しましょう。
git log
commit 60fac38abc402b3733aa5651513e3f25a7908257 (HEAD -> main)
Author: アカウント名 <メールアドレス>
Date: Mon Jun 2 13:42:58 2025 +0900
3行目のコミット
commit 547093a7e9c21a3f19f458c0e5225c8f9d250267
Author: アカウント名 <メールアドレス>
Date: Mon Jun 2 13:41:57 2025 +0900
25行目のコミット
commit 2334156677922d845e43766607b18f2d01f35b96
Author: アカウント名 <メールアドレス>
Date: Mon Jun 2 13:41:22 2025 +0900
1行目のコミット
このように3件のコミットができています。
今回は、25行目と書いた部分は本来2行目ですので、この部分をrebase
で編集してみましょう。
編集したいコミットの一つ前のコミットのid
をコピーします。
今回は「25行目のコミット」を編集したいので、一つ前の、「1行目のコミット」のid
をコピーします。commit
という文字の横にあるハッシュ値です。
(コピーしたら、q
でgit log
を抜けてください。)
git rebase -i
の後ろに、コピーしたコミットidを貼り付けます。
git rebase -i 2334156677922d845e43766607b18f2d01f35b96
こんな表示が出ます。
pick 547093a 25行目のコミット
pick 60fac38 3行目のコミット
# Rebase 2334156..60fac38 onto 2334156 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
Vim(シェル上で動くテキストエディタ)を操作して、コミット履歴を編集状態にします。
i
で編集モードに入ります。
編集したいコミット履歴のpick
をedit
に書き換えます。
edit 547093a 25行目のコミット
pick 60fac38 3行目のコミット
Esc
で編集モードを抜けて、:wq
で保存します。
すると、ターミナルにはこう出ていると思います。
git rebase -i 2334156677922d845e43766607b18f2d01f35b96
Stopped at 547093a... 25行目のコミット
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
この状態で、test.md
を修正します。
テキストエディタに戻ると、このように「25行目のコミット」のところまで戻っており、3行目の記述がありません。
1 行目
25 行目
では、25行目となっている部分を2行目に修正しましょう。
1 行目
2 行目
Ctrl
+ s
などで変更を保存します。
終わったら、修正をステージング、コミットします。
git add -A
git commit --amend -m "2行目"
このとき、コミットメッセージを変えないこともできます。
# コミットメッセージを変えないでコミット
git commit --amend --no-edit
今回は変えましょう。
rebase
を終了します。
git rebase --continue
すると、今変更した「2行目のコミット」を踏まえて、「3行目のコミット」が適用されます。
ここで、 コンフリクト が発生しました。
git rebase --continue
Auto-merging test.md
CONFLICT (content): Merge conflict in test.md
error: could not apply 60fac38... 3行目のコミット
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 60fac38... 3行目のコミット
今回は、2行目の部分を編集したため、その後の「3行目のコミット」内で、2行目の記述をどうするかでコンフリクトが起きています。
修正するためテキストエディタを開きましょう。
1 行目
<<<<<<< HEAD (現在の変更)
2 行目
=======
25 行目
3 行目
>>>>>>> 60fac38 (3行目のコミット) (入力側の変更)
このように表示されているかと思います。
「<<<<<<< HEAD
から =======
までが現在のブランチ(HEAD)での変更内容、=======
から >>>>>>> 60fac38...
までが再適用しようとしているコミット(この場合は 「3行目のコミット」)での変更内容を示しています。
これらのマーカーと不要なコードを削除し、正しいコードだけを残します。
どちらかの変更を自動で適用するボタンもあるので、ふだんはそれを使っても大丈夫です。
今回は、25行目を消して2行目に変えて、その下に3行目ができてほしいので、変更を一気に取り込むことはせず、手動で以下のように編集しましょう。
1 行目
2 行目
3 行目
コンフリクトを修正できたら、 改めてステージングします。 commit
はしません。
git add -A
もう一度rebase
モードを抜けます。
git rebase --continue
環境によっては、以下のような表示になるかもしれません。
git commit --amend -m "2行目のコミット"
[detached HEAD 6734819] 2行目のコミット
Date: Tue Jun 3 18:50:36 2025 +0900
1 file changed, 1 insertion(+)
3行目のコミット
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# interactive rebase in progress; onto 5802abb
# Last commands done (2 commands done):
# edit a8b2295 25行目のコミット
# pick d0a6592 3行目のコミット
# No commands remaining.
# You are currently rebasing branch 'main' on '5802abb'.
#
"~/repos/rebase-test3/.git/COMMIT_EDITMSG" 15L, 466B
これはGitが「次のコミットのメッセージを編集しますか?」と聞いています。編集のためにVimが開いています。
今回はこのままでいいので、:wq
を押して保存し、Vimを抜けましょう。
以下のような表示になっていれば、無事にrebase
モードを抜けることができています。
Successfully rebased and updated refs/heads/main.
こうすることで、今回手動でコンフリクトを解決してadd
した内容が、「3行目のコミット」の内容として保存されることになります。
rebase
はここまでです。
この時点で、ローカルリポジトリでは修正が完了しています。
最後に、リモートリポジトリへ強制push
します。
git push --force
これで、晴れてコミット履歴を改変し、正しい状態のファイルのみをGitHubに上げ直すことができました。
GitHubにはもう「25行目」という誤った記述はありません。
お疲れ様でした。
最後に
私は初めからPrivateリポジトリにしていたこともあり、rebase
するだけでなんとかことなきを得ました。
それでも、コミット履歴を改ざんしなくてはならないプレッシャー、使い慣れないVim操作、コンフリクトの解消…など、初心者には胃が痛い作業でした。
何が機密情報に当たるのか認識する必要性を痛感するとともに、「怪しければ入力しない」「安易に判断しない」という教訓にもなりました。
ただ、このgit rebase
、単純にコミットメッセージだけを修正したり、コミット履歴をきれいにしたりなど、ここまでのやらかしでないときにも十分使えます。
手数の一つとして持っておくに越したことはないでしょう。
参考サイト
コミットの修正方法について
こちらの記事では、コミットを修正する方法が複数紹介されています。何かあったときの対処を知るために、ご一読を推奨いたします。
rebase
の手順を簡単に振り返りたいときにもおすすめです。
また、生成AIに聞くとrebase
の代わりによく勧められる、git filter-repo
についても書かれています。
今回用いたrebase
との違いは、
-
rebase
:直前のcommit
や過去の単一のcommit
を修正したい場合 -
git filter-repo
:過去の複数のcommit
、または過去のすべてのcommit
を修正したい場合
と書かれています。
git filter-repo
は公式推奨のライブラリのようです。気になる方はGitHubページもどうぞ。
https://github.com/newren/git-filter-repo
実務の場での対応について
こちらの記事では、実務レベルでやってしまったときの対応について詳細に書かれています。
私の場合は、個人開発であり、かつ入力してしまった情報がMailtrapのみだったので、ここまではしませんでした。しかし、もしものときのために知っておくべき実践的な内容でした。
実際に実務の場でやってしまって困っている方、いざという時のために対応を知っておきたい方は、ぜひご一読ください。