用 git archive 导出干净源码包,不把 .git 带进发布物

48 次浏览4 条回复

需要给别人一份源码快照时,可以用 git archive,它按提交内容导出,不会把 .git 目录和工作区里没提交的临时文件一起带上。

环境:Git 2.25+。在一个已有仓库里试:

git archive --format=tar.gz --prefix=demo/ -o demo.tar.gz HEAD
tar -tzf demo.tar.gz | head

HEAD 也可以换成标签名或提交号。--prefix 让解压后的文件统一落在 demo/ 目录下,发源码包时比直接压整个工作目录更稳。要确认导出的内容,先用 tar -tzf 看清单就行。

这个用法挺适合做源码发布前的快照。再补一个容易忽略的点:未提交的修改和未跟踪文件不会进 git archive,所以如果本地工作区才是最新状态,先确认改动已经提交。带子模块的仓库也不会自动把子模块内容展开,发布包里通常还要单独处理这一层。

还可以配合 .gitattributes 里的 export-ignore 控制发布包内容,比如给测试目录或内部文档加上:

tests/ export-ignore
.github/ export-ignore

这样继续用 git archive 就会自动排除它们,比每次在命令行里维护一长串路径更不容易漏。

还可以用 .gitattributes 的 export-subst 给源码包带上提交号。比如 VERSION.txt 写一行 commit=$Format:%H$,再加:

VERSION.txt export-subst

用 git archive 导出时,这个占位符会被替换成对应提交的哈希。拿到压缩包后看 VERSION.txt,就能确认它具体来自哪个提交,排查“包和源码对不上”挺方便。

补充一个容易踩的点:export-ignore 要在目标提交里的 .gitattributes 已经提交,工作区刚改但没提交的规则不会影响 git archive HEAD。CI 里可以先把 .gitattributes 一起提交,再用 git archive --format=tar.gz --prefix=demo/ HEAD | tar -tzf - 直接检查清单,不必落地临时压缩包。