大きなバイナリファイルを追跡する場合、gitは非常に低速です


83

私のプロジェクトは6か月前のもので、gitは非常に遅いです。サイズが5MBから50MBの約30個のファイルを追跡します。これらはバイナリファイルであり、gitで保持します。これらのファイルがgitを遅くしていると思います。

サイズが5MBを超えるすべてのファイルをリポジトリから削除する方法はありますか?私はこれらのファイルをすべて失うことを知っています、そしてそれは私にとっては大丈夫です。

理想的には、すべての大きなファイル(> 5MB)を一覧表示するコマンドが必要です。リストが表示されたら、「OK」と言って、これらのファイルを削除し、gitを高速化します。

gitは私のマシンだけでなく、ステージング環境へのアプリのデプロイに約3時間かかることに注意してください。

したがって、修正は、リポジトリのユーザーだけでなく、サーバーにも影響を与えるものでなければなりません。


4
あなたはからのgitを使用して試すことができますgit-bigfilesプロジェクト
ヤクブNarębski

1
バイナリファイルの管理には、git-annexのようなものを使用してみてください。git-annex.branchable.com
Jed Schneider

誰かに役立つ場合は、Cygwinバージョンのgitがリベースにぶら下がっていたことを付け加えておきます。Git-Bashを使用したとき、同じリポジトリに問題はありませんでした。
Sridhar Sarnobat 2014

それでもそうなのかしら。圧縮効果が50%(またはその他の選択可能なX%)未満の場合は、すべて圧縮をオフにしてください。ある時点で、速度は明らかにハードウェアスペースを上回ります!
トリラリオン2015

回答:


125

ガベージコレクションをしますか?

git gc

これにより、小さなリポジトリの場合でも、速度に大きな違いが生じます。


8
これは、雑然としすぎると自動的に行われます。それが本当にOPに役立つとは思えません。
カスカベル2010年

@Jefromi、それは新しいですか?昨日1.7.1にアップグレードしましたが、それ以前は、使用していたバージョンが自動的に実行されませんでしたgc
kubi 2010年

@kubi:ええと、それは永遠に存在していませんが、まったく新しいものではありません-caf9de2(2007年9月14日)以降、または安定バージョンv1.5.4(2008年2月1日)以降、commit、merge、am、およびrebaseから呼び出されています)。
カスカベル2010年

1
git gc考え直してみると、とを呼び出すことはできません。そうしないcommitmergegit fsck --unreachable何も返されません。
kubi 2010年

4
それを見つけた。自動gc実行前のルーズオブジェクトのデフォルト数は6700です。これは、自動実行を見たことがない理由を説明しています。
kubi 2010年

79

説明

Gitは、小さなテキストファイルとその変更を効率的に保存できるため、小さなテキストファイルの膨大な履歴に非常に適しています。同時に、gitはバイナリファイルが非常に苦手であり、ファイルの個別のコピーを素朴に保存します(デフォルトでは少なくとも)。ご覧のとおり、リポジトリは巨大になり、その後遅くなります。

これはDVCSに共通の問題であり、クローンを作成するたびにすべてのファイルのすべてのバージョン(「リポジトリ全体」)をダウンロードするという事実によって悪化します。で、みんな窯は、より多くの唯一のオンデマンド履歴バージョンをダウンロードSubversionの、のように、これらの大きなファイルを処理するためのプラグインに取り組んでいます。

解決

このコマンドは、サイズが5MB以上の現在のディレクトリにあるすべてのファイルを一覧表示します。

find . -size +5000000c 2>/dev/null -exec ls -l {} \;

リポジトリの履歴全体からファイルを削除したい場合は、このアイデアを使用しgit filter-branchて履歴を調べ、大きなファイルの痕跡をすべて取り除くことができます。これを行った後、リポジトリのすべての新しいクローンはよりスリムになります。クローンを作成せずにリポジトリを学習したい場合は、manページに指示があります(「リポジトリを縮小するためのチェックリスト」を参照)。

git filter-branch --index-filter \
    'find . -size +5000000c 2>/dev/null -exec git rm --cached --ignore-unmatch {} \;'

警告の言葉:ツリーとインデックスには異なるファイルがチェックインされているため、これによりリポジトリが他のクローンと互換性がなくなります。あなたはもうそれらから押したり引いたりすることができなくなります。


4
注:これはUnix / Linuxバージョンのfindであり、Windowsのfind.exeではありません。
Craig Trader 2010年

1
+1。誤ったヒットがあった場合に備えて、find最初にの出力をファイルに送信し、リストを確認してから、を使用することをお勧めしますgit rm。または、git status大きなファイルを削除した後に確認しgit checkout HEAD <file>、誤って削除されたファイルを取り戻すために使用します。
カスカベル2010年

2
gitが「デフォルトで別々のコピーを保存する」というあなたのコメントは逆だと思います。リンクしたメールチェーン(thread.gmane.org/gmane.comp.version-control.git/146957/…)によると、デフォルトでは、gitはバイナリファイルを差分しようとします。これが問題の原因です。ストレージではありません。
アレクサンダーバード

16

これは、ネガティブで炎症を少なくすることを目的とした打ち切り改訂です。

Gitには、行ごとのテキストファイルではないファイルに関してはよく知られている弱点があります。現在、解決策はなく、コアgitチームがこれに対処する計画を発表していません。プロジェクトが小さい場合、たとえば100 MB程度の場合は、回避策があります。このスケーラビリティの問題に対処するためのgitプロジェクトのブランチが存在しますが、これらのブランチは現時点では成熟していません。他のいくつかのリビジョン管理システムには、この特定の問題はありません。リビジョン管理システムとしてgitを選択するかどうかを決定するときは、この問題を多くの要因の1つとして考慮する必要があります。


8
「Gitはよく知られている弱点を持っている...」 -要出典
Navの

6
私はそれを知っている。その実際の常識のときに引用符が必要な人。バイナリにgitを使用しないでください。PERFORCEまたは特殊な資産管理を使用します。
v.oddou 2014

1
@ v.oddouええと、「私はそれを知っている」と「その実際の常識」には違いがあります。これは、誰もがそれを知っているわけではなく、おそらくそれは完全に真実ではないということです。したがって、あらゆる種類の引用がこの答えを改善します。それは大丈夫ですが、確かに目立たず、バックアップされていません。
トリラリオン2015

2
まあ、火に燃料を追加するためではありませんが、「gitとバイナリファイルが遅い」をグーグル検索すると、gitでバイナリファイルを管理するのに問題があるユーザーを報告するリンクがたくさん見つかります。また、いずれかのSCMを使用する開発者は、各システムの長所と短所を知っています...そのため、バイナリファイルがリポジトリにスローされるとgitが非常に遅くなるという評判が生まれました。
ahiyaHiya 2016年

私が使用したすべての入門リソースで、gitがバイナリファイルで悪いことがわかります。これを修正するためにgit-annexが存在します。gitは素晴らしいですが、バイナリデータには適していません。バイナリ機能を追加するフォークにリンクして、人々が作業をサポートできるようにするとよいでしょう。
fuzzyTew

15

バイナリファイルとgitがそれらを処理する方法については特に何もありません。ファイルをgitリポジトリに追加すると、ヘッダーが追加され、ファイルはzlibで圧縮され、SHA1ハッシュの後に名前が変更されます。これは、ファイルの種類に関係なくまったく同じです。zlib圧縮には、バイナリファイルで問題となるものは何もありません。

しかし、いくつかの時点(プッシュ、gc)で、Gitはコンテンツをデルタ圧縮する可能性を検討し始めます。gitが類似したファイル(ファイル名など)を見つけた場合、それらをRAMに入れて、一緒に圧縮し始めています。100個のファイルがあり、それぞれが50Mbと表示されている場合、同時に5GBをメモリに入れようとします。これに、物事を機能させるためにさらにいくつかを追加する必要があります。コンピュータにこの量のRAMがない可能性があり、スワップを開始します。このプロセスには時間がかかります。

デルタ圧縮の深さを制限して、プロセスがそれほど多くのメモリを使用しないようにすることができますが、結果として圧縮の効率が低下します。(core.bigFileThreshold、delta属性、pack.window、pack.depth、pack.windowMemoryなど)

したがって、大きなファイルでgitを非常にうまく機能させるためにできることはたくさんあります。


4
これらの「デルタ」試行の発生を無効にする方法の説明については、ここを参照してください。
アレクサンダーバード

6

物事をスピードアップする1つの方法は、--depth 1フラグを使用することです。詳細については、manページを参照してください。私は優れたgitの第一人者ではありませんが、これはap4 getまたはaと同等のことを行うと言っsvn getていると思います。つまり、「すべてのファイルのすべてのリビジョンを常に提供する」のではなく、最新のファイルのみを提供します。何をgit cloneしますか。


1
これではリポジトリからプッシュできないため、有用性は限られています。
マーティンC.マーティン

4

それらのファイルはバイナリであるとgitに伝えましたか?

例:*.ext binaryリポジトリに追加.gitattributes


ファイルがバイナリであることをgitに伝えると、処理速度が上がると思います。
ニックヴァンダービルト2010年

gitのヒューリスティックが、ファイルが自動的にバイナリであると判断できない場合があります。
sml 2010年


2

私は2008年からWindowsとGNU / linuxの両方でGitを実行しており、追跡するファイルのほとんどはバイナリファイルです。私のリポジトリのいくつかは数GBで、Jpegやその他のメディアが含まれています。私は自宅と職場の両方でGitを実行している多くのコンピューターを持っています。

元の投稿で説明されているような症状は一度もありません。しかし、ほんの数週間前、私は古いWin-XPラップトップにMsysGitをインストールしましたが、ほとんど何をしても、gitは停止しました。2つまたは3つの小さなテキストファイルでのテストでさえ、途方もなく遅いものでした。1k未満のファイルを追加するために約10分話しています... gitプロセスは永遠に生き続けたようです。他のすべては、このコンピューターで期待どおりに機能しました。
最新バージョンから1.6にダウングレードしたところ、問題は解決しました...
同じブランドの他のラップトップがあります。同じIT部門によってインストールされたWin-XPも同じイメージで、バージョンに関係なくGitは正常に動作します。 ..したがって、その特定のコンピューターには何か奇妙なことがあるに違いありません。

また、バイナリファイルと圧縮を使用していくつかのテストを行いました。BMP画像があり、それに小さな変更を加えてコミットすると、gitgcは非常によく圧縮されます。したがって、私の結論は、圧縮はファイルがバイナリであるかどうかに依存しないということです。


-2

無視するようにファイルを設定するだけです。以下のリンクを参照してください。

http://help.github.com/git-ignore/


@Jefromi実際に私が投稿したリンクを見ると、2番目の段落にその場合の正確な対処方法を説明する指示があることがわかります。
joshlrogers 2010年

14
本当。しかし、あなたの答えの直接の内容は、「ファイルを追跡から削除してから無視する」ではなく、「ファイルを無視する」です。一般的に、別のサイトにリンクするよりも、ここに書く方が良いでしょう。
カスカベル2010年

-24

これgitがスケーラブルではないためです。

これはgitの深刻な制限であり、gitのアドボカシーによって溺れています。gitメーリングリストを検索すると、わずか100 MBの画像(たとえば、Webサイトやアプリケーションの場合)だけでgitがひざまずく理由を疑問に思う何百人ものユーザーが見つかります。問題は、ほとんどすべてのgitが「パッキング」と呼ばれる最適化に依存していることです。残念ながら、最小のテキストファイル(つまり、ソースコード)を除いて、パッキングは非効率的です。さらに悪いことに、履歴が増えるにつれて、効率が低下します。

これは本当に恥ずかしいgitの欠陥であり、「高速」と宣伝されており(証拠がないにもかかわらず)、git開発者はそれをよく知っています。なぜ彼らはそれを修正しなかったのですか?Photoshopドキュメント(* .psd)は独自の形式であるため、問題を認識しないgit開発者からの応答がgitメーリングリストにあります。はい、それは本当に悪いです。

結果は次のとおりです。

別のリポジトリを設定したくない小さなソースコードのみのプロジェクトにはgitを使用してください。または、分散型開発のgitのcopy-the-entire-repoモデルを利用したい小さなソースコードのみのプロジェクトの場合。または、単に新しいツールを学びたいとき。これらはすべてgitを使用する正当な理由であり、新しいツールを学ぶことは常に楽しいことです。

大規模なコードベース、バイナリ、膨大な履歴などがある場合は、gitを使用しないでください。リポジトリの1つはTBです。Gitはそれを処理できません。VSS、CVS、およびSVNはそれを問題なく処理します。(ただし、SVNは膨れ上がります。)

また、gitが成熟するまでの時間を与えます。まだ未成熟ですが、勢いがあります。やがて、Linusの実用的な性質がOSSの純粋主義者を克服し、最終的にgitはより広い分野で使用できるようになると思います。


15
この答えは本当に過度に否定的で炎症を起こします。はい、gitにはバイナリファイルのスケーラビリティの問題があります。コードに対しては非常にスケーラブルで高速です。CVS / SVNが多くの操作でディスクアクセスではなくネットワークアクセスを必要とするという事実を無視しても、速度の証拠はたくさんあります(あなたの主張は反対ですが)。gitを使って非常に楽しく巨大な歴史を持つ大規模なプロジェクトがたくさんあります。
カスカベル

8
そして...あなたはPhotoshopのことをハープしていますか?詳細な応答を書くのに時間を無駄にするつもりはありませんが、スレッド全体を読んだ場合はthread.gmane.org/gmane.comp.version-control.git/146957/…(ジョンがスレッドはあなたですか?)、現在のgitでこれを処理する最善の方法、将来どのように対処するか、なぜそれが最優先事項ではないのかについて、多くの合理的な回答があります。
カスカベル2010年

14
ええ、ここではあなたが正しいとは思いません。Gitは働く道を、否定に値するために、Linuxカーネルのためにあまりにもよく、「スケーラブルではありません。」
Andres Jaan Tack 2010年

1
このコメントは、それをバックアップするためのリンクまたはデータがあれば、より信頼できるでしょう。ところで、Mercurialについてどう思いますか?
vy32 2010年

3
世論を表明していないのかもしれませんが、OPの回答よりも「否定的」という点で反対票が多すぎたと思います。誰かがその年のバージョン管理フレーバーを気に入らないという理由だけで積み重ねるのではなく、反対意見を奨励する必要があります。GITは、バイナリファイルの追跡にはあまり適していません。しかし、それはソースコードには最適であり、それが主な目的であるため、Linuxカーネルで優れた機能を発揮します。
dyasta 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.