web-dev-qa-db-ja.com

gitはZipファイルをディレクトリとして、Zip内のファイルをblobとして扱うことができますか?

シナリオ

常に.Zipファイル内に保存されているいくつかのファイルを使用せざるを得ないと想像してください。 Zip内の一部のファイルは小さなテキストファイルで頻繁に変更されますが、他のファイルは大きくなりますが、幸運にも比較的静的です(画像など)。

これらのZipファイルをgitリポジトリ内に配置する場合、各Zipはblobとして扱われるため、リポジトリをコミットするたびに、Zipファイルのサイズだけ大きくなります...小さなテキストファイルが1つしかない場合でも内部が変更されました!

これが現実的である理由

MS Word 2007/2010 .docxおよびExcel .xlsxファイルはZipファイルです...

欲しいもの

たまたま、zipをファイルとしてではなくディレクトリとして扱い、その内容をファイルとして扱うようにgitに指示する方法はありますか?

利点

しかし、それはうまくいかなかったと言いますか?

余分なメタデータがないと、これはある程度のあいまいさを招くことに気づきます。git checkoutでは、gitはfoo.Zip/bar.txtを通常のディレクトリのファイルとして作成するか、Zipファイルとして作成するかを決定する必要があります。しかし、これは構成オプションによって解決できると思います。

それを行う方法の2つのアイデア(まだ存在しない場合)

  • git内でminizipIO::Compress::Zipなどのライブラリを使用する
  • gitが実際にZipファイルを最初にディレクトリとして見るように、ファイルシステム層を追加する
65

これは存在しませんが、現在のフレームワークに簡単に存在する可能性があります。差分を実行するときにgitがバイナリファイルまたはASCIIファイルの表示で異なる動作をするのと同じように、構成インターフェイスを介して特定のファイルタイプに特別な処理を提供するように指示できます。

コードベースを変更したくない場合は(これはすばらしいアイデアの1つですが)、 pre-commitおよびpost-checkoutフック を使用して、自分でスクリプトを作成することもできます。ファイルを解凍して保存し、チェックアウト時に.Zip状態に戻します。アクションを、git addで指定されたファイルのBLOB /インデックスのみに制限する必要があります。

どちらの方法も少々手間がかかります-それは、他のgitコマンドが何が起こっているのかを認識していてうまく機能しているかどうかの問題です。

21
Jeff Ferland

この質問にまだ興味があるかどうかはわかりません。私は同じ問題に直面していますが、これはgitファイルフィルターを使用する私の解決策です。

編集:最初に、はっきりとは言えないかもしれませんが、これ[〜#〜]は[〜#〜]OPの質問への回答です!コメントする前に文全体を読んでください。さらに、ソリューションを明確にするためのアドバイスを提供してくれた@Toon Krijtheに感謝します。

私の解決策は、フィルターを使用して、Zipファイルをモノリシックな拡張された(巨大な)テキストファイルに「フラット化」することです。 git add/commit中に、Zipファイルは通常のテキスト比較のためにこのテキスト形式に自動的に展開され、チェックアウト中には自動的に再度圧縮されます。

テキストファイルはレコードで構成され、各レコードはZip内のファイルを表します。したがって、このテキストファイルは、元のZipのテキストベースの画像であることがわかります。 Zip内のファイルがテキスト形式の場合は、テキストファイルにコピーされます。それ以外の場合は、テキスト形式ファイルにコピーされる前にbase64でエンコードされます。これにより、テキストファイルは常にテキストファイルになります。

このフィルターはZip内の各ファイルをblobにしませんが、バイナリファイルの変更は対応するbase64の更新で表すことができる一方で、テキストファイルは行ごとにマップされます(これは、差分の単位です)。これは、 OPが想像するもの。

詳細とプロトタイピングコードについては、次のリンクをご覧ください。

Zippey Gitファイルフィルター

また、このソリューションについて私にインスピレーションを与えた場所に感謝します: ファイルフィルターのしくみの説明

13
Sippey

bupを使用します(詳細は GitMinutes#24 にあります)

これは、大きな(非常にvery大きなものでも)ファイルを処理するように設計された唯一のgitのようなシステムです。つまり、Zipファイルのすべてのバージョンは、差分から(完全な追加ではなく)リポジトリを増やすだけです。コピー)

結果は、通常のGitコマンドが読み取れる実際のgitリポジトリです。

bupがGitとどのように異なるかについては、「 大きなファイルを含むgit 」で詳しく説明します。


その他の回避策(git-annexなど)は、「 git-annex with large files "。

11
VonC

http://tante.cc/2010/06/23/managing-Zip-based-file-formats-in-git/

(注: Ruben からのコメントによると、これは適切なdiffを取得することのみに関するものであり、解凍されたファイルのコミットに関するものではありません。)

〜/ .gitconfigファイルを開き(まだ存在しない場合は作成します)、次のスタンザを追加します。

[diff "Zip"] textconv = unzip -c -a

「unzip -c -a FILENAME」を使用してzipファイルをASCII text(unzip -c unzips to STDOUT)に変換します。次に、ファイルREPOSITORY /を作成/変更します。 gitattributesと以下を追加

* .pptx diff = Zip

これはgitに、指定されたマスクを計算するファイル(この場合は.pptxで終わるすべて)を計算するファイルの構成のZip差分記述を使用するように指示します。ここでgit diffはファイルを自動的に解凍し、ASCII出力を比較します。これは単に「バイナリファイルが異なる」よりも少し優れています。)一方、pptxファイルの対応するXMLという複雑な混乱につまり、あまり役に立ちませんが、テキストを含むZipファイル(たとえば、ソースコードアーカイブなど)の場合、これは実際には非常に便利です。

5
user649198

ファイルシステムにZipファイルをマウントする必要があると思います。私は使用していませんが、Fuseを検討してください。

http://code.google.com/p/Fuse-Zip/

WindowsおよびLinux用のZFSもあります。

http://users.telenet.be/tfautre/softdev/zfs/

2
Brad

多くの場合、Zip圧縮方法とファイルの順序が選択したものであることを期待しているため、アプリケーションの事前に圧縮されたファイルには問題があります。 Open Officeの.odfファイルにはその問題があると思います。

つまり、ものをまとめる方法としてany-old-Zipを単に使用している場合は、必要に応じて解凍して再圧縮するいくつかの単純なエイリアスを作成できるはずです。最新のMsysgit(別名Git for Windows)は、シェルコード側にZipとunzipの両方を備えているため、エイリアスで使用できます。

私が現在取り組んでいるプロジェクトでは、メインのローカルバージョン管理/アーカイブとしてzipを使用しているため、これらの何百ものzipをgitに吸い込むための実行可能なエイリアスのセットを取得しようとしています(そして、それらを再び取得します;-)。同僚が幸せであること。

2
Philip Oakley

RezipZippey by sippey と同様に、gitを使用してZipファイルをより適切に処理できます。

使い方

Zipベースのファイルを追加/コミットする場合、Rezipはそれをアンパックし、圧縮せずに再パックしてから、インデックス/コミットに追加します。圧縮されていないZipファイルでは、アーカイブされたファイルがas-isとしてコンテンツに表示されます(各ファイルの前のバイナリメタ情報とともに)。これらのアーカイブファイルがプレーンテキストファイルである場合、このメソッドはgitでうまく機能します。

利点

ZippeyよりもRezipの主な利点は、リポジトリに保存されている実際のファイルがZipファイルであることです。したがって、多くの場合、それを経由せずに取得した場合でも、それぞれのアプリケーション(たとえばOpen Office)でas-isで動作します圧縮して再パッキングするフィルター。

使い方

システムにフィルターをインストールします。

mkdir -p ~/bin
cd ~/bin

# Download the filer executable
wget https://github.com/costerwi/rezip/blob/master/Rezip.class

# Install the add/commit filter
git config --global --replace-all filter.rezip.clean "Java -cp ~/bin Rezip --store"

# (optionally) Install the checkout filter
    git config --global --add filter.rezip.smudge "Java -cp ~/bin Rezip"

<repo-root>/.gitattributesファイルに次のような行を追加して、リポジトリでフィルタを使用します。

[attr]textual     diff merge text
[attr]rezip       filter=rezip textual

# MS Office
*.docx  rezip
*.xlsx  rezip
*.pptx  rezip
# OpenOffice
*.odt   rezip
*.ods   rezip
*.odp   rezip
# Misc
*.mcdx  rezip
*.slx   rezip

textualの部分は、これらのファイルがdiffで実際にテキストファイルとして表示されるようにするためです。

2
hoijui