web-dev-qa-db-ja.com

大きなファイルを持つGit

状況

ProductionとDevelopmentの2つのサーバーがあります。実稼働サーバーには、テストのために開発者に配布する必要がある2つのアプリケーションと複数(6)のデータベース(MySQL)があります。すべてのソースコードは、開発サーバーの GitLab に保存され、開発者はこのサーバーでのみ作業しており、運用サーバーにはアクセスできません。アプリケーションをリリースすると、マスターは実稼働環境にログインし、Gitから新しいバージョンを取得します。データベースは大規模(それぞれ500M以上)であり、テストのために開発者にできるだけ簡単に配布する必要があります。

可能な解決策

  • 各データベースを単一のファイルにダンプするバックアップスクリプトの後に、各データベースを独自のブランチにプッシュするスクリプトを実行します。開発者は、ローカルコピーを更新する場合、これらのブランチの1つをプルします。

    これは機能していないことがわかりました。

  • 実稼働サーバー上のCronは、バイナリログを毎日保存し、そのデータベースのブランチにプッシュします。そのため、ブランチには毎日変更されるファイルがあり、開発者は持っていないファイルをプルします。現在のSQLダンプは、別の方法で開発者に送信されます。そして、リポジトリのサイズが大きくなりすぎたら、開発者に完全なダンプを送信し、リポジトリ内のすべてのデータをフラッシュして、最初から始めます。

ご質問

  • 解決策は可能ですか?
  • Gitがリポジトリにプッシュ/プルしている場合、ファイル全体をアップロード/ダウンロードしますか、それとも単に変更します(つまり、新しい行を追加するか、現在の行を編集します)?
  • Gitは非常に大きなファイルを管理できますか? いや.
  • リポジトリに保存されるリビジョンの数を設定するにはどうすればよいですか? 新しいソリューションでは関係ありません。
  • より良い解決策はありますか?このような大きなファイルをFTPなどでダウンロードすることを開発者に強制したくありません。
39
Jakub Riedl

rsync は、データベースの開発者用コピーを効率的に更新するのに適したオプションです。

デルタアルゴリズムを使用して、ファイルを増分更新します。そのようにして、変更された、または新しいファイルのブロックのみを転送します。もちろん、最初に完全なファイルをダウンロードする必要がありますが、後で更新する方が速いでしょう。

基本的に、gitクローンが提供する初期コピーを拡張することなく、gitフェッチと同様の増分更新を取得します。損失には履歴はありませんが、それは必要ないようです。

rsyncは、ほとんどのLinuxディストリビューションの標準部分です。Windowsで必要な場合は、パッケージ化されたポートが利用可能です。 http://itefix.no/cwrsync/

データベースを開発者にプッシュするには、次のようなコマンドを使用できます。

rsync -avz path/to/database(s) Host:/folder

または、開発者は必要なデータベースをプルすることができます:

rsync -avz DATABASE_Host:/path/to/database(s) path/where/developer/wants/it
25
PeterSW

本当に、本当に、本当に大きなバイナリファイルをGitリポジトリにチェックインしたくないのです。

追加する各更新は、リポジトリの全体サイズに累積的に追加されます。つまり、Gitリポジトリは、ブランチの履歴全体をローカルに保存するため、Gitリポジトリのクローン作成とディスクスペースの使用に時間がかかります。つまり、誰かがブランチをチェックアウトするときに、データベースの最新バージョンをダウンロードするだけで済むわけではありません。また、以前のバージョンをすべてダウンロードする必要があります。

大きなバイナリファイルを提供する必要がある場合は、それらを別のサーバーに個別にアップロードし、開発者が大きなバイナリファイルをダウンロードできるURLでテキストファイルをチェックインします。 FTPは実際にはbetterオプションの1つです。FTPはバイナリファイルを転送するために特別に設計されているためですが、HTTPはおそらくもっと簡単です。

29
Amber

git-annexのようなソリューションを見ることができます。これは、ファイルの内容をgit(!)にチェックすることなく、gitで(大きな)ファイルを管理することに関するものです。
(2015年2月: GitLabのようなホスティングサービスがネイティブに統合します
GitLabはgit-annexなどで大きなファイルをサポートしますか? 」を参照してください。

her answerAmber で説明されているように、gitは大きなファイルを管理しません。

だからと言って、Gitがいつかはもっとうまくやれないというわけではありません。
From GitMinutesエピソード92013年5月、以下も参照)、From Peff(Jeff King) 、36'10 '':

(転写)

人々が20 GB、30 GB、または40 GB、時にはTBサイズのリポジトリを保存することに関心を持っている他のすべての大きなリポジトリの領域があります。互いにあまりうまく処理できない、非常に大きなファイルと非常に大きなバイナリファイルを持つことから。

それは一種の未解決の問題です。いくつかのソリューションがあります:git-annexはおそらく最も成熟したものであり、基本的に資産をgitに入れず、大規模な資産を資産サーバーに置き、pointerを置きます。 gitに。

アセットがgitのconceptuallyであり、そのオブジェクトのSHA1がツリーに入り、コミットIDに入るSHA1の一部である場合、そのようなことをしたいと思います。それらすべてのもの。
したがって、gitの観点からは、リポジトリの一部ですが、下位レベル、オブジェクトストレージレベル、conceptual履歴グラフより下のレベルでは、すでに複数のオブジェクトを保存する方法: loose objectspacked objects があります。オブジェクトを保存する新しい方法があります。ここにはありませんが、アセットサーバーで利用できます」などです。

Thomas Ferris Nicolaisen )ああクール...

git-annexのようなものの問題は、一度使用すると、その時点で行った決定に永遠に縛られることになります。 200 MBが大きいと判断した場合、資産サーバーに保存することになります。その後、0 MBになっているはずです。履歴に永久にエンコードされます。
そのため概念的にと言うと、このオブジェクトはgitレベルでin gitリポジトリであり、それへのポインタではなく、アセットへのポインタでもありませんサーバー、actualオブジェクトがあり、それらの詳細を低レベルで、ストレージレベルで処理することで、さまざまな決定を下すことができ、さらには- changeディスクに実際に保存する方法に関するあなたの決定。

今のところ優先度の高いプロジェクトではありません...


3年後の2016年4月、 Git Minutes 4 のインタビューが含まれています Michael Haggertyfrom GitHub およそ31 '(ありがとうあなた インタビューのクリスチャン・クーダー )。

彼は かなり長い間、リファレンスバックエンドに特化 です。
彼は David Turnerの仕事 を現時点で最も興味深いものとして引用しています。 ( Davidのgit/git forkの現在の "pluggable-backends"ブランチを参照

(転写)

Christian Couder(CD):目標は、たとえばgit refをデータベースに保存することですか? Michael Haggerty(MH):ええ、2つの興味深い側面があると思います。1つ目は、さまざまなソースエントリ参照をプラグインできることです。エントリ参照は、緩やかな参照と パックされた参照 の組み合わせとしてファイルシステムに保存されます。
ルーズリファレンスはリファレンスごとに1つのファイルであり、パックリファレンスは多くのリファレンスのリストを含む1つの大きなファイルです。

したがって、これは特にローカルでの使用に適したシステムです。通常の人には実際のパフォーマンスの問題はありませんが、参照が削除された後に参照reflogを保存できないなど、同様の問題で作成された新しい参照と競合する可能性があるため、いくつかの問題があります名前。参照名がファイルシステムに保存されるという問題もあります。そのため、同じ名前で大文字と小文字が異なる参照を持つことができます。
だから、これらは一般に異なるリファレンスバックエンドシステムを持つことで修正できるものです。
そして、David Turnerのパッチシリーズのもう1つの側面は、lmdbと呼ばれるデータベースに参照を保存する変更です。これは非常に高速です。ファイルバックエンドよりもパフォーマンスが優れているメモリベースのデータベース。

[パッキングの高速化に関するその他の考慮事項、および参照パッチの広告に従います]

25
VonC

Gitで隠されたコードから参照されるファイルの補助記憶装置を持つことは、ほとんどの人が行く場所です。 git-annexはかなり包括的なように見えますが、多くのショップでは、SQLダンプのような大きなファイルにFTPまたはHTTP(またはS3)リポジトリを使用しています。私の提案は、日付と同様にハッシュにメタデータの一部、特にチェックサム(おそらくSHA)を詰め込むことにより、gitリポジトリ内のコードを補助ストレージ内のファイルの名前に結び付けることです。

  • したがって、各auxファイルは、ベース名、日付、およびSHA(一部のバージョンn)の合計を取得します。
  • ワイルドファイルターンオーバーがある場合、SHAのみを使用すると、ハッシュ衝突の小さなながらも実際の脅威が発生するため、日付(エポック時間またはISO日付)が含まれます。
  • 結果のファイル名をコードに入れて、補助チャンクが具体的には参照によって含まれるようにします。
  • すべてのAUXファイル名をgit grepに簡単に記述できるように名前を構成し、コミットのリストを取得するのが簡単になるようにします。これにより、古いものをある時点で廃止することもできます。また、Gitリポジトリからコードをアクティブ化する前に、古いものを(まだ)破壊することなく、本番環境に新しいAUXファイルを引き出すために展開システムと統合できます。

巨大なファイルをgit(またはほとんどのリポジトリ)に詰め込むと、しばらくするとgitのパフォーマンスに悪影響を及ぼします-git cloneたとえば、20分はかかりません。一方、参照によるファイルの使用は、一部の開発者が大きなチャンクをまったくダウンロードする必要がないことを意味します(git clone)、オッズはほとんどが実稼働環境でデプロイされたコードにのみ関係しているためです。もちろん、走行距離は異なる場合があります。

1
Alex North-Keys

大きなファイルをアップロードすると、問題やエラーが発生します。これは通常起こります。主にgitはアップロードするファイルが50MB未満をサポートしています。 gitリポジトリに50MBを超えるファイルをアップロードするには、大きなファイル(.mp4、.mp3、.psd)などのアップロードに協力する別のアシスタントをインストールする必要があります。

大きなファイルをgitにアップロードする前に知っている基本的なgitコマンドがあります。これは、githubでアップロードするための構成です。インストールする必要がありますgitlfs.exe

int-it from lfsinstall.exe



次に、いくつかの異なるコマンドとともにgitの基本コマンドを使用する必要があります

git lfs install
git init
git lfs track ".mp4"
git lfs track ".mp3"
git lfs track ".psd"
git add .
git add .gitattributes
git config lfs.https://github.com/something/repo.git/info/lfs.locksverify false 
git commit -m "Add design file"
git Push Origin master` ones

あなたはそれを見つけるかもしれませんlfs.https://github.com/something/repo.git/info/lfs.locksverify false使用中にプッシュする場合、Pushコマンド中の指示と同様

0
Ariful Islam