2011-11-03 153 views
46

場景可以將zip文件作爲目錄和zip文件中的文件作爲blob處理?

想象,我不得不與我的一些文件總是存儲在內部.zip文件的工作。 zip中的一些文件是小文本文件,並且經常更改,而其他文件較大,但幸運的是相當靜態(例如圖像)。

如果我想將這些壓縮文件放入git存儲庫中,則每個壓縮文件都被視爲blob,因此每當我提交壓縮文件時,存儲庫都會增大...即使只有一個小文本文件變了!

爲什麼這是現實

的MS Word 2007/2010 .docx和Excel .xlsx文件是ZIP文件...

我想要什麼

是存在的,以任何機會,一種告訴git不要將zip文件視爲文件的方式,而是將其視爲目錄並將其內容視爲文件?

優勢

但它不能正常工作,你說呢?

我意識到,如果沒有額外的元數據,這將引起歧義的一些量:在git checkout混帳必須決定是否要創建foo.zip/bar.txt作爲普通目錄中的文件或zip文件。然而,這可以通過配置選項來解決,我想。

兩個想法如何可以做到(如果不存在的話)

  • 使用圖書館內的git如minizipIO::Compress::Zip
  • 莫名其妙地增加了文件系統層,使得實際的git看到zip文件作爲目錄開始
+1

用'.DOCX場景'文件是有道理的,但在其他許多情況下,您可能需要考慮使用git來正常跟蹤各個文件,並且只使用'make'等相應的構建工具*構建* .zip。 – pixelistik

+0

考慮到兩個看起來不同的zip文件可以保存完全相同的數據(例如,使用兩個不同的壓縮級別壓縮兩次的文本文件),這變得更加棘手。雖然很容易在兩個版本的解壓縮文件之間用很少的信息來表示差異,但我猜想代表兩個版本的壓縮文件(這實際上是git必須做的)之間的區別,儘可能少的信息是非-不重要的。 – HelloGoodbye

+0

你有沒有結束[Jeff's answer](https://stackoverflow.com/a/8001900/321973)或其他任何東西的實施解決方案?我想知道除了[對於tar檔案](https://stackoverflow.com/q/37000849/321973)基本相同,這應該產生兼容的答案... –

回答

15

這並不存在,但它可以很容易地在存在目前的框架。正如git在執行diff時顯示二進制文件或ascii文件的行爲不同一樣,可以通過配置界面告訴它對某些文件類型提供特殊處理。

如果您不想更改代碼庫(儘管您的想法很酷),也可以使用pre-commit and post-checkout hooks來解壓並存儲文件,然後返回它們在結帳時將其添加到.zip狀態。您必須將操作限制爲僅由git add指定的那些文件blob /索引。

無論哪種方式都有點工作 - 這只是一個其他git是否意識到發生了什麼並能很好地發揮作用的問題。

+0

掛鉤看起來像是一個很好的方向;我簡單地想過,但不確定它是否可行。預提交鉤子可以修改文件系統和暫存區域嗎? –

+1

@Jonas你有沒有最終這樣做,是否有機會發佈一個工作的解決方案?我很樂意有效地跟蹤git中電子表格的變化,而CSV僅適用於我們的目的。 – Ruben

+0

對不起,我從來沒有跟進過我自己...... –

2

我想你將需要安裝一個zip文件到文件系統。我沒有用它,但考慮FUSE:

http://code.google.com/p/fuse-zip/

另外也ZFS用於Windows和Linux:

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

+0

如果我理解正確,fuse-zip可以在文件系統和git之間分層,但是zfs必須被構建到*'git'中,對吧?太糟糕了,我並不總是在Linux下使用該回購,否則fuse-zip將是一個非常好的主意。 –

2

對於應用程序來說,預壓縮文件經常出現問題,因爲他們預計壓縮方法和文件順序將成爲他們選擇的文件順序。我相信公開的.odf文件有這個問題。

也就是說,如果您只是簡單地使用any-old-zip作爲保存東西在一起的方法,那麼您應該能夠創建一些簡單的別名,這些別名將在需要時解壓縮並重新壓縮。最新的Msysgit(又名Git for Windows)現在可以在shell代碼上壓縮和解壓縮,所以你可以在別名中使用它們。

我目前正在使用的項目使用zips作爲主要的本地版本控制/歸檔,所以我也試圖獲得一組可行的別名,用於將這幾百個zip文件吸入到git中(並將它們再次取出;-)讓同事們開心。

+3

我剛剛爲Word 2010做了一些測試 - 它看起來相當寬容(用不同的字尺寸「放氣」 deflate64'和更改由7zip生成的zip文件中的文件順序都不會導致Word關閉)。關於使用別名,我希望避免任何額外的手動步驟...目前我的大部分提交都通過TortoiseGit。 –

9

使用bup

它是唯一的git-like系統專門用來對付大(甚至很非常大)文件,這意味着一個zip文件的每個版本(在GitMinutes #24詳細介紹)只會增加從其三角洲的回購(而不是一個完整的額外副本)

結果是一個實際的git回購,一個常規的Git命令可以讀取。

予詳細說明如何bup從GIT中的不同之處 「git with large files」。


任何其他的解決方法(如git-annex)並不完全令人滿意,如在 「git-annex with large files」 詳述。

+1

這看起來非常適合非常大的文件,該場景更多地面向XML,比如docx和xlsx(通常很小)。你會得到一個較小的回購大小與bup,但你會得到不同的實際變化的XML? – Ruben

+0

@Ruben這是面向大型文件的大小或數量。但在差異方面與git沒有多大區別。 – VonC

+0

看起來很有意思,但是你可以在你的實際git repo中使用它嗎? – kutschkem

5

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

(注:每從Ruben評論,這只是有關獲取適當的DIFF雖然不是犯解壓文件。)

打開你的〜/的.gitconfig文件(如果創建不存在的話),並添加 以下節:

[DIFF 「拉鍊」] = TEXTCONV解壓-c -a

它所ð oes使用「unzip -c -a FILENAME」將您的zip文件 轉換爲ASCII文本(將unzip -c解壓縮到STDOUT)。接下來是 創建/修改文件REPOSITORY/.gitattributes並加入以下內容

*。pptx diff = zip

它告訴git使用配置中的zip-diffing描述爲 文件提供給定的掩碼(本例中以 .pptx結尾的所有內容)。現在,git diff會自動解壓縮這些文件,並區分 ASCII輸出,這比「二進制文件不同」要好一些。 另一方面,爲了解決pptx文件的相應XML 令人費解的混亂,它對於包括 文本(例如源代碼歸檔文件)在內的ZIP文件沒有多大幫助,但實際上這相當方便地使用 。

+0

這只是關於獲取適當的差異,而不是關於提交解壓縮文件。 – Ruben

+0

謝謝。這回答了我想解決的問題,即在git diffing時顯示gzip文件中的文本文件的更改。我用'[diff'gzip「] = zcat'和'* .gz diff = gzip'。 – spazm

10

不確定是否有人對這個問題仍然感興趣。我面臨着同樣的問題,這是我使用git文件過濾器的解決方案。

編輯: 首先,我可能沒有說清楚,但這是OP的問題的答案!在評論之前閱讀整個句子。此外,感謝@Toon Krijthe的建議,澄清解決方案。

我的解決方案是使用一個過濾器將zip文件「平面化」爲單片擴展(可能是巨大的)文本文件。在git添加/提交過程中,zip文件會自動擴展爲正常文本格式的文本格式,並且在結帳時,它會自動再次壓縮。

文本文件由記錄組成,每個記錄表示zip中的文件。所以你可以將這個文本文件作爲原始zip的基於文本的圖像。如果zip中的文件是文本文件,則將其複製到文本文件中;否則,它在複製到文本格式文件之前是base64編碼的。這使得文本文件始終是一個文本文件。

儘管這個過濾器並沒有使zip中的每個文件都成爲一個blob,但是文本文件被映射爲line,這是diff的單元,而二進制文件的更改可以通過更新相應的base64來表示,我認爲這相當於OP想象的。

有關詳細信息和原型代碼,你可以閱讀下面的鏈接:

Zippey Git file filter

此外,信貸啓發了我對這一解決辦法的地方: Description of how file filter works

+0

此過濾器仍在開發中,如果您有任何疑問或任何建議讓我知道。 – Sippey

+1

我試了一下,我認爲它應該適合我。我只是在文檔中添加了一些內容,即文本文件列表zippey.py必須進行修改,以包含任何想要zippey.py識別爲文本文件的文件類型。 – mteng

+0

這個過濾器很棒!非常感謝發佈這個。 –