2011-11-03 158 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

这个过滤器很棒!非常感谢发布这个。 –