Git:履歴コミットからファイルを削除する方法は?


113

ID 56f06019でコミットしています(たとえば)。そのコミットで私は誤って大きなファイル(50Mb)をコミットしました。別のコミットでは、同じファイルを適切なサイズ(小さい)で追加します。今私が複製したときの私のレポは重すぎる:(私のレポのサイズを減らすためにレポ履歴からその大きなファイルを削除する方法?


私の場合、それは大きなファイルではなく、データベースクレジットを含む構成ファイルです。私はgitを勉強していましたが、当時は.gitignoreに気づいていませんでした。
ラシ、


回答:


165

Pro Gitブックの第9章には、オブジェクトの削除に関するセクションがあります。

ここで手順を簡単に説明しましょう。

git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/mylarge_50mb_file' \
    --tag-name-filter cat -- --all

前述のリベースオプションと同様に、filter-branchリライト操作です。履歴を公開している場合は--force、新しい参照をプッシュする必要があります。

このfilter-branchアプローチは、rebaseアプローチよりもかなり強力です。

  • 一度にすべてのブランチ/参照で作業することができ、
  • その場でタグの名前を変更します
  • ファイルの追加以降、いくつかのマージコミットがあったとしても、正常に動作します。
  • (a)ブランチの履歴でファイルが数回(再)追加/削除された場合でも、正常に動作します。
  • 無関係な新しいコミットを作成するのではなく、それらに関連付けられたツリーを変更するときにそれらをコピーします。これは、署名されたコミット、コミットノートなどのものが保持されることを意味します

filter-branch バックアップも保持するため、reflogsとガベージコレクションを期限切れにしない限り、リポジトリのサイズはすぐには減少しません。

rm -Rf .git/refs/original       # careful
git gc --aggressive --prune=now # danger

1
これは、windows cmd.exeでは機能しないようです。ただし、cygwinで問題なく動作するようです。
偽の名前

2
上記のgitフィルターブランチを、単一引用符ではなく二重引用符を使用して機能させました(Windows Server 2012 cmd.exe)
JCii

1
私にとってうまくいったのは、このフィルターブランチのコマンドラインでした。 git filter-branch --force --index-filter 'git rm --ignore-unmatch --cached PathTo/MyFile/ToRemove.dll' -- fbf28b005^.. その後rm --recursive --force .git/refs/originalrm --recursive --force .git/logs 私はを使用しましたがgit prune --expire nowgit gc --aggressive これは上記の正確な手順よりもうまく機能しました。貴重なGit Proブックへのリンクを含めていただき、ありがとうございます。
dacke.geo 2015年

filter-branchコマンドの後、.gitフォルダーのサイズを下げる唯一の方法は、次のコマンドを実行することでした:stackoverflow.com/questions/1904860/…git -c gc.reflogExpire = 0 -c gc。 reflogExpireUnreachable = 0 -c gc.rerereresolved = 0 \ -c gc.rerereunresolved = 0 -c gc.pruneExpire = now gc "$ @"
Steve

レポを縮小するために、私はgitのフィルタ分岐ドキュメントに記載されているコマンドを使用:git-scm.com/docs/...
ルドビクRonsin


0

インタラクティブモードでgit rebaseを実行する必要があります。ここで例を参照してください。GitHubコミットを削除するにはどうすればよいですか?そして古いコミットを削除する方法

コミットがHEAD-10コミットの場合:

$ git rebase -i HEAD~10

履歴の編集後、「新しい」履歴をプッシュする必要があります。+強制するを追加する必要があります(プッシュオプションの refspecを参照):

$ git push origin +master

他の人がすでにリポジトリを複製している場合は、履歴を変更しただけなので、通知する必要があります。


3
大きなファイルは履歴から削除されませ。また、力押しの標準的な方法があるgit push --forceか、git push -f(分岐プッシュターゲットを知っている人を必要としない)
sehe

質問に基づいて、新しいファイルは古いファイルとまったく同じ、つまり同じパスです。これがgit rm、パス上で直接使用できない理由です。
ロイック・ドールAnterroches

2
@sehe、巨大なファイルでコミットを削除するリベースを行うと、それは永久になくなります。
フォンブランド2013

@vonbrandあなたがリベースしたブランチからのみ。「from」ブランチが削除されることを想定していません。しかし、ええ、リビジョンツリーブランチを削除すると、役に立ちます:_
sehe

@sehe確かに、問題のコミットを含むすべてのブランチを追跡する必要があります。リポジトリの茂みの前にある場合は、多くの再編成が必要になります。しかし、リベースこのためのツールです。
フォンブランド2013

0

私はwindows https://stackoverflow.com/a/8741530/8461756で次の回答を使用してみました

一重引用符はWindowsでは機能しません。二重引用符が必要です。

以下は私のために働いた。

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PathRelativeRepositoryRoot / bigfile.csv"---all

大きなファイルを削除した後、変更をgithub masterにプッシュすることができました。


0

簡単なコマンドを使用して削除できます

 git rm -r -f app/unused.txt 
 git rm -r -f yourfilepath
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.