1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

機密情報をGitHubに上げちゃった人は、git rebaseを使ってコミット履歴を書き換えよう!という話

Last updated at Posted at 2025-06-05

はじめに結論

.env.exampleなどに機密情報を載せたままGitHubにpushしてしまった人は、gitcommit履歴を 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に変更します。

image.png

このようにして、悪意あるクロールの対象からいち早く外れましょう。

私の場合は、最初から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回繰り返して、コミット履歴を作りましょう。

test.md
1 行目
git add -A
git commit -m "1行目のコミット"
test.md
1 行目
25 行目 //この行を追加。あえて間違った数字を入れます
git add -A
git commit -m "25行目のコミット"  #ついでにコミットメッセージも間違えておきましょう。
test.md

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という文字の横にあるハッシュ値です。

(コピーしたら、qgit 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で編集モードに入ります。

編集したいコミット履歴のpickedit に書き換えます。

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行目の記述がありません。

test.md

1 行目
25 行目

では、25行目となっている部分を2行目に修正しましょう。

test.md

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行目の記述をどうするかでコンフリクトが起きています。

修正するためテキストエディタを開きましょう。

test.md

1 行目
<<<<<<< HEAD (現在の変更)
2 行目
=======
25 行目
3 行目
>>>>>>> 60fac38 (3行目のコミット) (入力側の変更)

このように表示されているかと思います。

<<<<<<< HEAD から ======= までが現在のブランチ(HEAD)での変更内容、======= から >>>>>>> 60fac38... までが再適用しようとしているコミット(この場合は 「3行目のコミット」)での変更内容を示しています。
これらのマーカーと不要なコードを削除し、正しいコードだけを残します。

どちらかの変更を自動で適用するボタンもあるので、ふだんはそれを使っても大丈夫です。

今回は、25行目を消して2行目に変えて、その下に3行目ができてほしいので、変更を一気に取り込むことはせず、手動で以下のように編集しましょう。

test.md

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のみだったので、ここまではしませんでした。しかし、もしものときのために知っておくべき実践的な内容でした。
実際に実務の場でやってしまって困っている方、いざという時のために対応を知っておきたい方は、ぜひご一読ください。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?