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リモートリポジトリに誤ってpushしてしまったコミットログを削除する

Posted at

はじめに

リモートリポジトリのコミットログを削除したい時ってありませんか?
本来ならそんなことをしてはいけないのですが、それでもどうしても削除したいときは今回の方法で削除することができます。

事前準備

ここではリポジトリを作成し、コミットログを用意します。

リポジトリの作成

実施するにあたってのリポジトリを作成します。
今回は samplerepo というリポジトリ名で行います。
スクリーンショット 2024-11-25 9.52.15.png

コミットログ作成(初回)

作成したらまずはコミットログを用意します。

clone
% git clone git@github.com:hogehoge/samplerepo.git
Cloning into 'samplerepo'...
warning: You appear to have cloned an empty repository.
ディレクトリ移動
% cd samplerepo 

今回は README.md を作成してそれをコミットすることでログを作成します。

README.md作成
% echo "# samplerepo" >> README.md
add
% git add README.md 
commit
% git commit -m "first commit"
[main (root-commit) 7d796d7] first commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
push
% git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 224 bytes | 224.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:hogehoge/samplerepo.git
 * [new branch]      main -> main

以下のように README.md が追加されていることが確認できます。

スクリーンショット 2024-11-25 22.03.53.png

コミットログ作成(2回目)

今度は test.txt を作成するコミットログを残します。

test.txt作成
% touch test.txt
add
% git add test.txt 
commit
% git commit -m "test.txt"
[main 4e2d57e] test.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test.txt
push
% git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 277 bytes | 277.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:hogehoge/samplerepo.git
   7d796d7..4e2d57e  main -> main

test.txt というファイルが追加されていることが確認できます。

スクリーンショット 2024-11-25 22.04.56.png

また、コミットログを確認すると2つのログが存在することも確認ができます。

スクリーンショット 2024-11-25 22.05.06.png

以上で準備完了です。

コミットログの削除

それではコミットログを削除したいと思います。
今回は最初にコミットした 「first commit」 というログを削除します。

コミットログの確認

現在は以下のようなコミットログがローカルリポジトリで確認ができると思います。

log
% git log
commit 4e2d57e85ca9d73816973639049492b4056d22fe (HEAD -> main, origin/main)
Author: Kohei Yamada <kohei@hengjiu.jp>
Date:   Mon Nov 25 22:04:34 2024 +0900

    test.txt

commit 7d796d79c6f92e983fc1d68c3a65a8b31f573cfd
Author: Kohei Yamada <kohei@hengjiu.jp>
Date:   Mon Nov 25 22:02:07 2024 +0900

    first commit

削除ではここで確認できるハッシュ値を使います。

コミット履歴の削除

先ほど確認した 「first commit」 のハッシュ値を使って以下のようにコマンドを実行します。
7d796d79c6f92e983fc1d68c3a65a8b31f573cfd の部分は適宜置き換えてください。

コミット履歴削除
% git filter-branch --commit-filter '
    if [ "$GIT_COMMIT" = "7d796d79c6f92e983fc1d68c3a65a8b31f573cfd" ]; then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi' HEAD
WARNING: git-filter-branch has a glut of gotchas generating mangled history
	 rewrites.  Hit Ctrl-C before proceeding to abort, then use an
	 alternative filtering tool such as 'git filter-repo'
	 (https://github.com/newren/git-filter-repo/) instead.  See the
	 filter-branch manual page for more details; to squelch this warning,
	 set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...

Rewrite 4e2d57e85ca9d73816973639049492b4056d22fe (2/2) (0 seconds passed, remaining 0 predicted)    
Ref 'refs/heads/main' was rewritten

改めてログを確認するとローカルリポジトリでは削除されていることが確認できます。

log
% git log                            
commit 04d43daf983095854a595126b484cd5d4561eb05 (HEAD -> main)
Author: Kohei Yamada <kohei@hengjiu.jp>
Date:   Mon Nov 25 22:04:34 2024 +0900

    test.txt

この状態でリモートリポジトリへプッシュします。
通常のプッシュだとエラーになるため --force オプションを付けて強制的にプッシュします。

push
% git push --force
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 266 bytes | 266.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:hogehoge/samplerepo.git
 + 4e2d57e...04d43da main -> main (forced update)

リモートリポジトリでも履歴が削除されていることが確認できました。

スクリーンショット 2024-11-25 22.07.38.png

以上でコミットログの削除については以上となります。

コミットログを全て削除してみる

気になったので試してみたいと思います。
もう一つのコミットログも同じ方法で削除してみます。

コミット履歴削除
% git filter-branch --commit-filter '
    if [ "$GIT_COMMIT" = "04d43daf983095854a595126b484cd5d4561eb05" ]; then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi' HEAD

WARNING: git-filter-branch has a glut of gotchas generating mangled history
	 rewrites.  Hit Ctrl-C before proceeding to abort, then use an
	 alternative filtering tool such as 'git filter-repo'
	 (https://github.com/newren/git-filter-repo/) instead.  See the
	 filter-branch manual page for more details; to squelch this warning,
	 set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...

Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

無事に削除できたのかなと思いきや、

Cannot create a new backup. A previous backup already exists in refs/original/

というメッセージが表示されています。

このエラーについて調べたところ、Gitのバックアップシステムに関する問題とのことです。

Gitではフィルタリング操作(例えば git filter-branch を使った履歴の変更)を行うと、元の参照が refs/original/ にバックアップされます。ですが、今回のような対応を行った後だとすでにバックアップが存在してしまうため、再度実施しようとすると新しいバックアップを作成できずこのエラーが発生しまうとのことです。

実際に git log で確認したところコミット履歴は削除されていないことがわかります。

log
% git log                            
commit 04d43daf983095854a595126b484cd5d4561eb05 (HEAD -> main)
Author: Kohei Yamada <kohei@hengjiu.jp>
Date:   Mon Nov 25 22:04:34 2024 +0900

    test.txt

これを解消するためにはバックアップを削除する必要があります。

バックアップ削除
% rm -rf .git/refs/original/refs/heads/main

それでは改めて履歴の削除を行います。

コミット履歴の削除
% git filter-branch --commit-filter '       
    if [ "$GIT_COMMIT" = "4e2d57e85ca9d73816973639049492b4056d22fe" ]; then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi' HEAD
WARNING: git-filter-branch has a glut of gotchas generating mangled history
	 rewrites.  Hit Ctrl-C before proceeding to abort, then use an
	 alternative filtering tool such as 'git filter-repo'
	 (https://github.com/newren/git-filter-repo/) instead.  See the
	 filter-branch manual page for more details; to squelch this warning,
	 set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...

Rewrite 4e2d57e85ca9d73816973639049492b4056d22fe (1/1) (0 seconds passed, remaining 0 predicted)    
Ref 'refs/heads/main' was deleted
fatal: Not a valid object name HEAD

無事に削除ができたみたいです。

log
% git log
fatal: your current branch 'main' does not have any commits yet

今度は

fatal: Not a valid object name HEAD

というメッセージが表示されましたが、これは Git が現在のリポジトリに有効な HEAD がない( HEAD がどのブランチやコミットも指していない)という意味になります。
今回の処理で履歴を全部削除してしまった状態なのでこのメッセージが表示されたようです。

実際にbranchを確認してみると何も表示されません。

branch確認
% git branch

履歴を全て削除したことで HEAD がどれを指しているかの履歴も消えてしまったようです。
この場合は pull をすれば元に戻ります。

pull
% git pull
branch
% git branch
* main

ということでコミットログは削除できるが全てのコミットログを削除することはできないということがわかりました。

おわりに

普段はブランチ切ってコミットしてマージしてという単純なことしか行ってなかったので、今回のようなことをきっかけに Git への知識が少し深まったかなと思います。

参考

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?