git可以将zip文件作为目录和zip文件中的文件视为blob吗?

问题描述 投票:58回答:7

场景

想象一下,我被迫使用一些总是存储在.zip文件中的文件。 zip中的一些文件是小文本文件并经常更改,而其他文件更大但幸运的是相当静态(例如图像)。

如果我想将这些zip文件放在git存储库中,每个zip都被视为一个blob,所以每当我提交时,存储库的大小都会增加zip文件...即使只有一个小文本文件发生变化!

为什么这是现实的

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

我想要的是

是否有任何机会告诉git不将拉链视为文件,而是作为目录并将其内容视为文件?

优点

但是,它说不行吗?

我意识到如果没有额外的元数据,这将导致一些歧义:在git checkout git将不得不决定是否将foo.zip/bar.txt创建为常规目录或zip文件中的文件。但是,我认为这可以通过配置选项解决。

两个想法如何完成(如果它还不存在)

  • 在git中使用minizipIO::Compress::Zip等库
  • 以某种方式添加一个文件系统层,以便git实际上将zip文件视为开始的目录
git zip msysgit
7个回答
21
投票

这不存在,但它可以很容易地存在于当前框架中。正如git在执行diff时显示二进制或ascii文件的行为不同,可以通过配置界面告诉它对某些文件类型提供特殊处理。

如果您不想更改代码库(虽然这是一个很酷的想法),您也可以使用pre-commit and post-checkout hooks解压缩并存储文件,然后将它们返回到.zip,为自己编写脚本。在结账时说。您必须将操作限制为仅由git add指定的那些文件blob / index。

无论哪种方式都是一些工作 - 这只是一个问题,其他git赞扬是否知道发生了什么,并发挥得很好。


12
投票

不确定是否还有人对这个问题感兴趣。我面临同样的问题,这是我使用git文件过滤器的解决方案。

编辑:首先,我可能不会说清楚,但这是OP的问题的答案!在评论之前阅读整个句子。此外,感谢@Toon Krijthe提供的建议,以澄清解决方案。

我的解决方案是使用过滤器将zip文件“扁平化”为单片扩展(可能是巨大的)文本文件。在git add / commit期间,zip文件将自动扩展为此文本格式以进行正常的文本区分,并且在结帐时,它会再次自动压缩。

文本文件由记录组成,每个记录代表zip中的文件。所以你可以认为这个文本文件是原始zip的基于文本的图像。如果zip中的文件是契约中的文本,则将其复制到文本文件中;否则,在复制到文本格式文件之前,它是base64编码的。这使文本文件始终保持为文本文件。

虽然这个过滤器不会使zip中的每个文件成为blob,但是文本文件是逐行映射的,这是diff的单位,而二进制文件的更改可以通过更新它们对应的base64来表示,我认为这相当于OP想象的是什么。

有关详细信息和原型代码,您可以阅读以下链接:

Zippey Git file filter

此外,相信这个激发了我这个解决方案的地方:Description of how file filter works


11
投票

使用bup(在GitMinutes #24中详细介绍)

它是唯一一个用于处理大型(甚至非常大)文件的类似git的系统,这意味着每个版本的zip文件只会增加其delta的repo(而不是完整的附加副本)

结果是一个实际的git repo,一个普通的Git命令可以读取。

我详细介绍了bup在“git with large files”中与Git的不同之处。


任何其他解决方法(如git-annex)并不完全令人满意,详见“git-annex with large files”。


5
投票

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

(注意:根据Ruben的评论,这只是关于获得适当的差异,而不是关于提交解压缩的文件。)

打开〜/ .gitconfig文件(如果已经存在则创建)并添加以下节:

[diff“zip”] textconv = unzip -c -a

它的作用是使用“unzip -c -a FILENAME”将zipfile转换为ASCII文本(解压缩-c解压缩到STDOUT)。接下来是创建/修改文件REPOSITORY / .gitattributes并添加以下内容

* .pptx diff = zip

它告诉git使用配置中的zip-diffing描述来计算给定掩码的文件(在这种情况下,所有内容都以.pptx结尾)。现在git diff自动解压缩文件并区分ASCII输出,这比仅仅“二进制文件不同”好一点。另一方面,对于pptx文件的相应XML的复杂混乱,它没有多大帮助,但对于包括文本的ZIP文件(例如源代码存档),这实际上非常方便。


2
投票

我想你需要将zip文件挂载到文件系统。我没有用它,但考虑FUSE:

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

还有适用于Windows和Linux的ZFS:

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


2
投票

通常,应用程序的预压缩文件存在问题,因为他们希望zip压缩方法和文件顺序是他们选择的。我相信开放式办公.odf文件有这个问题。

也就是说,如果你只是使用any-old-zip作为保持一起的方法,你应该能够创建一些简单的别名,这些别名将在需要时解压缩并重新压缩。最新的Msysgit(又名Git for Windows)现在在shell代码端同时具有zip和unzip,因此您可以在别名中使用它们。

我目前正在开发的项目使用zip作为主要的本地版本控制/存档,所以我也试图获得一组可行的别名,用于将这些数百个zips吸入git(并将它们再次取出;-) so同事们很开心。


2
投票

Rezip类似,Zippey by sippey允许使用git以更好的方式处理ZIP文件。

这个怎么运作

在添加/提交基于ZIP的文件时,在将其添加到索引/提交之前,Rezip将其解压缩并重新打包而不进行压缩。在未压缩的ZIP文件中,归档文件在其内容中显示为原样(以及每个文件之前的一些二进制元信息)。如果这些归档文件是纯文本文件,则此方法将与git很好地配合使用。

优点

Rezip优于Zippey的主要好处是存储在存储库中的实际文件仍然是ZIP文件。因此,在许多情况下,它仍然可以与相应的应用程序(例如Open Office)一起工作,即使它是在不经过重新打包压缩过滤器的情况下获得的。

如何使用

在您的系统上安装过滤器:

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部分是这样的,这些文件实际上显示为差异中的文本文件。

© www.soinside.com 2019 - 2024. All rights reserved.