如何从git归档中排除文件?
给定一个简单的测试存储库,其中包含两个文件,如何从git归档中排除文件?,git,git-archive,Git,Git Archive,给定一个简单的测试存储库,其中包含两个文件,a和b,我可以获得特定文件的列表: $ git ls-files a a $ git ls-files . ':!b' a $ git archive HEAD a | tar tf - a $ git archive HEAD . ':!b' | tar tf - a b 或不包括特定文件的所有文件的列表: $ git ls-files a a $ git ls-files . ':!b' a $ git archive HEAD a |
a
和b
,我可以获得特定文件的列表:
$ git ls-files a
a
$ git ls-files . ':!b'
a
$ git archive HEAD a | tar tf -
a
$ git archive HEAD . ':!b' | tar tf -
a
b
或不包括特定文件的所有文件的列表:
$ git ls-files a
a
$ git ls-files . ':!b'
a
$ git archive HEAD a | tar tf -
a
$ git archive HEAD . ':!b' | tar tf -
a
b
我可以创建特定文件的存档:
$ git ls-files a
a
$ git ls-files . ':!b'
a
$ git archive HEAD a | tar tf -
a
$ git archive HEAD . ':!b' | tar tf -
a
b
但我无法创建除特定文件之外的所有文件的存档:
$ git ls-files a
a
$ git ls-files . ':!b'
a
$ git archive HEAD a | tar tf -
a
$ git archive HEAD . ':!b' | tar tf -
a
b
在我的真实存储库中,使用特定文件的存档不是我的选项,因为它超过了最大命令行参数长度
我知道我可以通过export ignore
属性将要排除的文件列表存储在.gittributes
中,但该列表是动态生成的。我可以自动更改文件,但在再次提交之前,不会拾取更改
是否有其他调用可以在不需要再次提交的情况下工作?您可以创建一个tar,然后删除不需要在其中的文件夹和文件
git archive HEAD -o archive.tar
tar -f archive.tar --delete listoffiles1
tar -f archive.tar --delete listoffiles2
tar -f archive.tar --delete listoffiles..
tar -f archive.tar --delete listoffilesN
通过这种方式,您可以拆分命令行,使其保持在最大cli参数长度以下。我认为您几乎可以做到这一点:属性可以从多个位置读取,其中,
.gittributes
是最常见的属性。第二个被认为是每个存储库配置的是$GIT\u DIR/info/attributes
引用手册:
请注意,默认情况下,属性取自
正在存档的树。如果要调整输出的方式
在事实发生后生成(例如,您未添加适当的
export ignore
在其.gittributes
中,调整签出的.gittributes
文件
根据需要,使用--worktree attributes
选项。或者你可以保留
归档数据库中的任何树时应应用的必要属性
$GIT\u DIR/info/attributes
文件
因此,如果可能的话,将您的列表粘贴到该文件,然后执行git archive
另一种方法是不使用git archive
,而只使用tar
工作树传递tar
接受文件的--exclude from
命令行选项。这对于裸存储库不起作用,但是如果您在归档之前能够签出内容,那么可以通过执行git read tree
和git checkout index
来完成,并提供正确的$git_index_文件
和$git_work_tree
env。变量
另一种可能的解决方法是逆转这种方法:tar
(至少是GNU tar)支持一种鲜为人知的选项,即能够从管道中的存档中删除内容
基本上,你能做到
$ tar -C a_path -c -f - . \
| tar -f - --wildcards --delete '*.pdf' >result.tar
因此,管道中的第一个tar
会归档所有内容,而第二个会传递所有内容,但与*.pdf
shell全局模式匹配的文件除外
因此,如果使用shell globs指定要删除的文件可以符合命令行限制,只需将
git archive
的输出通过管道传输到tar
prcoess,它将删除不需要的内容。除了将export ignore
放入(提交的).gittributes
之外,还可以将其放入(未提交)$GIT_DIR/info/attributes
文件。或者将.gittributes
保持为未提交状态,并使用--worktree attributes
选项,这也可能不太好,因为它会使工作树变脏。使用GIT 2.20版(Windows)和Gitolite服务器(未知版本)这适用于排除名为“b”的文件和文件夹:
这也适用于:
git archive HEAD . ":(exclude)b" | tar tf -
请注意,我必须在Windows平台上使用双引号,不能确定其他平台。感谢您提供的详细答案。我认为对我来说,
。git/info/attributes
不一定是最符合逻辑的方法,但它最适合我现有的方法,如果我将来需要更多的方法,我可以将其更改为tar--delete
。