すでに削除した大きなファイルがあるため、GitHubにプッシュできません


272

現在私は持っています

  1. 空のGitHubリポジトリ
  2. SSHサーバーリポジトリ(メイン)
  3. ローカルリポジトリ

SSHサーバーリポジトリは最新のリポジトリ(本番サイト)だったので、そこからローカルにGitクローンを作成しました。次に、git pushGitHub を実行しようとしました。

すべてがうまくいったが、それはそれがfilename.gzがGitHubには大きすぎることについて何かを言った。このファイルは必要なかったので、いくつかのGitコマンドを実行してGitキャッシュから削除し、SSHサーバーにプッシュバックしました。

大きなファイルはローカルで表示されgit diffませんが、何も返されず、Git Pushが「Everything is up-to-date」を返しても、SSHサーバー上にあります-プッシュしようとすると、ファイルがローカルリポジトリに表示されませんGitHubそれでもエラーが発生する

リモート:エラー:ファイルfpss.tar.gzは135.17 MB。これは、GitHubのファイルサイズ制限である100 MBを超えています

GitHubヘルプにリストされている「問題の修正」の手順を実行したので、それで十分ではありませんか?

ローカルでない場合、またはgit status / diff / pushにリストされていない場合、ファイルはどのようにエーテルに残っていますか?


2
ファイルはまだ履歴に残っています。おそらくファイルを追加および削除したコミットを破棄することにより、履歴を破棄する必要があります。
Shahbaz 2013年

@Shahbaz私はこのサイトにリストされている「問題の修正」の下の手順を実行しました...それで十分ではなかったでしょうか?help.github.com/articles/working-with-large-files
ケビンW.

そこでのコマンドは私のgitの知識よりも進んでいるので、実際にはわかりません。とにかく、git log -- the_big_fileが何かを返す場合、ファイルはまだ履歴にあります。
Shahbaz 2013年

何も返さない@Shahbaz> <
ケビンW.

ファイルが存在する他のブランチもプッシュしている可能性がありますか?また、ファイルがまだサーバー上にある場合、なぜgit pushすべてが最新であると言うのでしょうか?履歴を変更したので、プッシュは不可能であり、強制する必要があると不平を言うはずです。
Shahbaz 2013年

回答:


446

使用できます

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

これにより、そのファイルの履歴のすべてが削除されます。問題は、ファイルが履歴に存在することです。

このコマンドはコミットのハッシュを変更します。これは、特に共有リポジトリーで実際の問題になる可能性があります。結果を理解せずに実行しないでください。


23
私のために働いたが、私はそれを「強制」しなければならなかった:git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file / dir>' -f HEAD
alexoviedo999

30
このコマンドはコミットのハッシュを変更します。これは、特に共有リポジトリーで実際の問題になる可能性があります。結果を理解せずに実行しないでください。
Chris

6
<file / dir>を、問題の原因となっているファイルまたはディレクトリの名前に置き換えますか?
David Rhoden

12
これらの変更をすべてのブランチに適用する場合は、--all代わりにフラグを使用する必要があることに注意してくださいHEAD
Nick Spreitzer

9
私は取得しています:Rewrite 657560fa18c030bcfac9132ce1c3541e84a5bc2c (1/10) (0 seconds passed, remaining 0 predicted) /usr/lib/git-core/git-filter-branch: 1: eval: Syntax error: end of file unexpected
ジョアン・アブランテス

68

スカッシュの方がより便利だと思いましたfilter-branch。私は次のことをしました:

  1. 大きなファイルをローカルで削除します。
  2. ローカル削除をコミットします。
  3. コミットのソフトリセットバックXの数(私のためにそれが3でした): git reset --soft HEAD~3
  4. 次に、すべての変更をまとめて再コミットします(別名、スカッシュ)。 git commit -m "New message for the combined commit"
  5. 押しつぶされたコミットをプッシュします。

特殊なケース(ユーザー@lituoから):上記の方法が機能しない場合は、このケースがある可能性があります。コミット1には大きなファイルが含まれており、コミット1のプッシュは大きなファイルのエラーが原因で失敗しました。Commit 2は大きなファイルを削除しましたgit rm --cached [file_name]が、Commit 2のプッシュは依然として失敗しました。上記と同じ手順に従いますがHEAD~3、を使用する代わりにを使用しますHEAD~2


2
私にとってはうまくいきました、スカッシュプッシュが機能する前に、3つのコミットからの変更をローカルリポジトリに再度マージする必要がありました。
dasWesen

5
これは、トップの回答よりもはるかに優れています。一番上の答えはコミット履歴全体を台無しにしてしまいます。
manic.coder

私の問題は解決しませんでした
Hirak Sarkar

3
これは、リポジトリを完全に無効にすることなく、コミットされていない、またはコミットされた大きなファイルを修正する唯一の答えです!それがトップに移動することができるように:-) Upvoted
Ælex

1
@しかし、私はラッパークラスではありません。どうもありがとうございました。これは魅力のように働きました:)
POOJA GUPTA

63

あなたが助けを求める前にあなたがすでにあなたのリポジトリをいじり回しているなら、これは私が非常に役立つと思ったものです。最初のタイプ:

git status

この後、あなたはの線に沿って何かを見るはずです

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

重要な部分は「2コミット」です。ここから先に進み、次のように入力します。

git reset HEAD~<HOWEVER MANY COMMITS YOU WERE BEHIND>

したがって、上記の例では、次のように入力します。

git reset HEAD~2

入力すると、「git status」は次のようになります。

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

そこから、大きなファイルを削除できます(まだ削除していない場合)。作業を失うことなく、すべてを再コミットできます。
これは特別な返信ではないことはわかっていますが、お役に立てば幸いです。


11
勝者。シンプルでクリーンで効果的なgitビルドのソリューション。このような愛の答え。
Reece Daniels

3
これが最善の解決策です。
wrahool

40

ファイルが最新のコミット追加されていて、リモートリポジトリにプッシュしていない場合は、ファイルを削除してコミットを修正できます

git rm --cached giant_file
    # Stage "giant_file" for removal with "git rm"
    # Leave it on disk with "--cached". if you want to remove it from disk
    # then ignore the "--cached" parameter
git commit --amend -CHEAD
    # Commit the current tree without the giant file using "git commit"
    # Amend the previous commit with your change "--amend" 
    # (simply making a new commit won't work, as you need
    # to remove the file from the unpushed history as well)
    # Use the log/authorship/timestamp of the last commit (the one we are
    # amending) with "-CHEAD", equivalent to --reuse-message=HEAD
git push
    # Push our rewritten, smaller commit with "git push"

1
ファイルはGitのインデックスにはもうないので、このソリューションは動作しません(それはその結果untrackedでファイルリストgit status
loretoparisi

何も起こりません。これを適用した後、ファイル数の合計は減りましたが、プロセスを99%表示した後、再びスタックしました。私が見逃している提案はありますか?
CoDe 2017年

4
-CHEADの意味?
Aerin 2017年

1
最後のコミットではなく特定のコミットからこれを試したい場合はどうなりますか?私は試しましたgit rm --cached giant_file commit_idが、うまく
いき

@puifais前のコミットに戻し、これらの手順を実行してから、現在のコミットとマージします。これが最善のアプローチかどうかは
わかり

13

同様の問題があり、上記手順を使用してファイルを削除しました。それは完全に機能しました。

次に、削除する必要がある2番目のファイルでエラーが発生しました。 remote: error: File <path/filename> is 109.99 MB; this exceeds GitHub's file size limit of 100.00 MB

私は同じ手順を試しましたが、エラーが発生しました: "A previous backup already exists in <path/filename>"

このWebサイトでの調査から、次のコマンドを使用しました。git filter-branch --force --index-filter "git rm --cached --ignore-unmatch <path/filename>" --prune-empty --tag-name-filter cat -- --all

うまくいき、大きなファイルは削除されました。

信じられないことに、プッシュはまだ別のエラーで失敗しました: error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 104 fatal: The remote end hung up unexpectedly

これは.git構成ファイルを直接変更して修正しました- postBuffer = 999999999

その後、プッシュが通過しました!


1
(上記のように)大きなファイルを削除する際に対処しなければならないもう1つの問題は、フォルダーの1つにハッシュ#文字が含まれていることでした。これにより、通常のgit操作ではまったく問題が発生しませんgit rmでしたが、ファイルの完全なリポジトリパス名を指定し、#をエスケープして機能させるために必要でした
jacanterbury

これも私にとってはうまくいきました。reset hard簡単なプッシュでページ下部のステップを回避しました。 czettner.com/2015/07/16/…–
モンテヘイワード

これは、「git push -f origin」も実行した後に機能しました
kezzos

12

大きなファイルを削除した後でも、GitHubがリポジトリを拒否するのはなぜですか?

Gitはプロジェクトの完全な履歴を保存するため、プロジェクトからファイルを「削除」しても、Gitリポジトリはその履歴にファイルのコピーを保持しており、別のリポジトリ( GitHub)の場合、Git リモートリポジトリにローカルリポジトリと同じ履歴(つまり、履歴内の同じ大きなファイル)があることを要求します。

GitHubでリポジトリを受け入れるにはどうすればよいですか?

プロジェクトのGit履歴をローカルでクリーンアップし、不要な大きなファイルをすべての履歴から削除してから、今後は「クリーンアップされた」履歴のみを使用する必要があります。影響を受けるコミットのGitコミットIDが変更されます。

Gitリポジトリから大きなファイルを削除するにはどうすればよいですか?

Git履歴から不要な大きなファイルを削除するための最良のツールは、BFG Repo-Cleanergit-filter-branchです。これは、Git履歴から不要なファイルを削除するために特別に設計されたものよりも簡単で高速な代替手段です。

使用方法の指示に注意深く従ってください、コア部分はこれだけです:

$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git

サイズが100MBを超えるファイル(最新のコミットにないもの)は、Gitリポジトリの履歴から削除されます。次に、を使用git gcして、死んだデータを削除できます。

$ git gc --prune=now --aggressive

BFGは通常、を実行する場合よりも少なくとも10倍から50倍高速git-filter-branchで、一般的にははるかに使いやすくなっています。

完全な開示:私はBFG Repo-Cleanerの作成者です。


1
私のケースには、つぶれを防ぐ追加の合併症がありました。BFGツールはうまく機能しました。ありがとう。
dantopa

これは驚異的な解決策です
SexualPotatoes

5

上記の方法をすべて試しましたが、どれもうまくいきませんでした。

それから私は自分の解決策を思いつきました。

  1. まず、クリーンで最新のローカルリポジトリが必要です。すべてのクソ大きなファイルを削除します。

  2. 次に、repoフォルダーの外側に新しいフォルダーを作成し、「Git create repository here」を使用して新しいGitリポジトリにします。これをnew_local_repoと呼びましょう。これだよ!上記のすべての方法で、履歴をクリーンアップする必要があると言われました。

  3. 古い、乱雑なローカルリポジトリから新しい美しいリポジトリにファイルをコピーします。フォルダーアイコンの緑色のロゴが消えることに注意してください。これは新しいリポジトリであるため、有望です。

  4. ローカルブランチにコミットしてから、リモートの新しいブランチにプッシュします。それをnew_remote_branchと呼びましょう。新しいローカルリポジトリからpushする方法がわからない場合は、Googleで確認してください。

  5. おめでとうございます!クリーンで最新のコードをGitHubにプッシュしました。リモートマスターブランチが不要になった場合は、new_remote_branchを新しいマスターブランチとして作成できます。方法がわからない場合は、Googleで確認してください。

  6. 最後のステップは、めちゃくちゃになった古いローカルリポジトリを削除するときです。将来的には、new_local_repoのみを使用します。


4

私は同じ問題を抱えており、答えはどれもうまくいきませんでした。私は次の手順で解決しました:

1.大きなファイルを含むコミットを見つける

git log --all -- 'large_file`

一番下のコミットは、結果リストで最も古いコミットです。

2.最も古いものの直前のものを見つけます。

git log

あなたが得たとしましょう:

commit 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

3. Gitリベース

git rebase -i 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

ヒント

  1. リストアイテム
  2. drop大きなファイルを含むコミットを選択するだけです。
  3. リベース中に競合に遭遇して修正し、それを使用git rebase --continueして、完了するまで続行することができます。
  4. リベース中に問題が発生した場合は、を使用git rebase --abortしてキャンセルしてください。


1

大きなファイル/フォルダーを作業フォルダー内に保持するソリューション

これは、ここで尋ねられた問題(回答1から)を解決するために機能した行です。

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

このコマンドは、file / dirが作業ツリー内にある場合、file / dirも削除します。

ファイル/フォルダーを作業ツリー内に保持する場合は、次の手順を実行することをお勧めします。

  1. そのエラーの実行後 git reset HEAD^
  2. 問題のファイル/フォルダーを `` .gitignore```ファイルに追加します。

  3. git add .他のファイル/フォルダーをキャプチャする可能性がありますが、.gitignoreファイルをキャプチャする必要がある通常どおり続行します。次はgit commit -m"message"、そしてついにgit push origin <branch_name>


0

これでうまくいきました。github Squashing Gitからのドキュメントはgit reset origin / masterをコミットします

git checkout master && git pull;
git merge feature_branch;
git add . --all;
git commit -m "your commit message"

ここでドキュメントを見つける


0

最初の答えに追加します。

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch'ヘッド

origin / masterからのマ​​ージの競合が発生します。

あなたのブランチと 'origin / master'は分岐しており、それぞれ114と109の異なるコミットがあります。(「git pull」を使用してリモートブランチを自分のものにマージします)

これを実行してください

git reset-ハードオリジン/マスター

これは、ステージングされた変更とステージングされていない変更をすべて破棄し、現在のローカルブランチのすべてを忘れて、origin / masterとまったく同じにします。


0

それで、私は特定の状況に遭遇しました:gitlabからリポジトリーを複製しました。100mbより大きいファイルが含まれていますが、git履歴のある時点で削除されました。その後、新しいgithub private repoを追加して新しいrepoにプッシュしようとすると、悪名高い「ファイルが大きすぎます」エラーが発生しました。この時点で、元のgitlabリポジトリにアクセスできなくなりました。ただし、bfg-repo-cleanerマシンのローカルリポジトリを使用して、新しいプライベートgithub レポジトリにプッシュすることはできました。

$ cd ~
$ curl https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar > bfg.jar
$ cd my-project
$ git gc
$ cd ../
$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-project
$ cd my-project
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git remote -v # confirm origin is the remote you want to push to
$ git push origin master

0

ファイルが追跡履歴に保存されている場合があります。次の手順を試してください。

  1. git commit、大きなファイルがリストされた作成モードが表示されている場合は、次のようにします。
  2. git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch filename' HEAD。コンソールに次の文字で終わる一連の書き換えが表示されます。

    rm 'ファイル名'および

    最後の行Refが書き直されました。

終わった。

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