预提交 Git 挂钩可以压缩目录并将其添加到存储库吗?
Can a pre-commit Git hook zip a directory and add it to the repository?
我正在开发 Wordpress 插件。我的开发目录包含许多特定于开发的内容(例如 Grunt 文件、Sass 文件、git 存储库本身等)。
显然,我不想分发包含所有这些开发文件的文件夹;人们在下载我的 Wordpress 插件时不想要几 MB 的 Grunt 文件。
不过,到目前为止,我的 "release" 过程一直很麻烦:
- 提交 Git 更改
- 压缩整个文件夹
- 打开 zip 文件并删除 .git 文件夹、grunt 文件和所有其他特定于开发的文件
- 发布新的 zip
我不知道完成此操作的最佳方法,但我 非常 隐约熟悉 Git 钩子,我有这样的想法:我可以设置一个 Git 挂钩,只将需要的生产文件压缩到一个 ZIP 文件中,并将其与 repo 一起存储吗? 这样,每次我提交时它都会自动创建一个新版本 ZIP。
这可能吗?如果是这样,有人能指出我正确的方向吗?
哦还有,我在Windows(·_·;)。所以我希望有办法在 Windows.
上做到这一点
我不能代表Windows发言,但是:
- 技术上可以在预提交挂钩中做这种事情。
- 不要。
修改 "what you will commit" 的预提交钩子很烦人(如果不出意外,它违反了 "rule of least astonishment",您的版本控制系统只存储您告诉它要存储的版本)。除此之外,存储大型预压缩二进制文件会干扰 git 将 space 保存在包文件中的尝试,并且会导致存储库快速膨胀、性能不佳、运行 内存不足,等等。 ZIP 存档 是 预压缩的二进制文件,因此表现不佳。
一般来说,更合理的 "hook-y" 处理发布的方法是设置一个 "release server" 来推送新发布,并让推送触发存档生成。 (有很多方法可以在没有单独的服务器/存储库的情况下做到这一点,你可以用更拉式的方式来做,但是推式很容易说明。)
[编辑: 本来考虑过git archive
,没想到可以方便的排除文件,所以改写如下。所以,比较好,应该是首选。在某些情况下,由于某些原因,git archive
可能不会这样做,我将保留它作为替代方案。]
例如,这里有一个服务器端 post-receive
钩子代码片段,它检查名称匹配 release*
的分支是否已被推送到,如果是,则调用 shell 带有分支名称的函数(每个这样的分支一次):
#! /bin/sh
NULL_SHA1=0000000000000000000000000000000000000000
scan()
{
local oldsha newsha fullref shortref
local optype
while read oldsha newsha fullref; do
case $oldsha,$newsha in
$NULL_SHA1,*) optype=create;;
*,$NULL_SHA1) optype=delete;;
*) optype=update;;
esac
case $fullref in
refs/heads/*)
reftype=branch
shortref=${fullref#refs/heads/}
;;
*)
reftype=other
shortref=fullref
;;
esac
case $optype,$reftype,$shortref in
create,branch,release*|update,branch,release*)
do_release $shortref;;
esac
done
}
scan
(以上大部分是样板,我已将其精简为要点)。您将不得不编写 do_release
函数,它可能类似于(完全未经测试):
do_release()
{
local tmpdir=/tmp/build.$$ # or use mktemp -d
# $tmpdir/index is git's index; $tmpdir/t is the work tree
trap "rm -rf $tmpdir; exit 1" 1 2 3 15
rm -rf $tmpdir
mkdir $tmpdir/t
GIT_INDEX_FILE=$tmpdir/index GIT_WORK_TREE=$tmpdir/t git checkout
# now clean out grunt files and make zip archive
(cd $workdir/t; rm -rf grunt; zip ../t.zip .)
# put completed zip archive in export location, name it
# based on the branch name
mv $workdir/t.zip /place/where/zip/files/live/.zip
# clean up temp dir now, and no longer need to clean up
# on signal related abort
rm -rf $tmpdir
trap - 1 2 3 15
}
实际上有一个命令,git archive
。
git archive master -o wizzo-v1.13.0.zip
请参阅 EXAMPLES
部分,您可以 select 路径,为它们添加前缀,通过输出扩展定义自定义后处理,以及一些更小的调整。
另请参阅 ATTRIBUTES
部分:您可以给文件 -- 任意模式,实际上 -- 一个 export-ignore
属性以将它们从存档中排除。
它有更多方便的花花公子,您可以从远程存储库获取档案,扩展任意 git log --pretty=format:
占位符,git 联机帮助页绝对值得您投入任何时间。
我正在开发 Wordpress 插件。我的开发目录包含许多特定于开发的内容(例如 Grunt 文件、Sass 文件、git 存储库本身等)。
显然,我不想分发包含所有这些开发文件的文件夹;人们在下载我的 Wordpress 插件时不想要几 MB 的 Grunt 文件。
不过,到目前为止,我的 "release" 过程一直很麻烦:
- 提交 Git 更改
- 压缩整个文件夹
- 打开 zip 文件并删除 .git 文件夹、grunt 文件和所有其他特定于开发的文件
- 发布新的 zip
我不知道完成此操作的最佳方法,但我 非常 隐约熟悉 Git 钩子,我有这样的想法:我可以设置一个 Git 挂钩,只将需要的生产文件压缩到一个 ZIP 文件中,并将其与 repo 一起存储吗? 这样,每次我提交时它都会自动创建一个新版本 ZIP。
这可能吗?如果是这样,有人能指出我正确的方向吗?
哦还有,我在Windows(·_·;)。所以我希望有办法在 Windows.
上做到这一点我不能代表Windows发言,但是:
- 技术上可以在预提交挂钩中做这种事情。
- 不要。
修改 "what you will commit" 的预提交钩子很烦人(如果不出意外,它违反了 "rule of least astonishment",您的版本控制系统只存储您告诉它要存储的版本)。除此之外,存储大型预压缩二进制文件会干扰 git 将 space 保存在包文件中的尝试,并且会导致存储库快速膨胀、性能不佳、运行 内存不足,等等。 ZIP 存档 是 预压缩的二进制文件,因此表现不佳。
一般来说,更合理的 "hook-y" 处理发布的方法是设置一个 "release server" 来推送新发布,并让推送触发存档生成。 (有很多方法可以在没有单独的服务器/存储库的情况下做到这一点,你可以用更拉式的方式来做,但是推式很容易说明。)
[编辑: 本来考虑过git archive
,没想到可以方便的排除文件,所以改写如下。所以,git archive
可能不会这样做,我将保留它作为替代方案。]
例如,这里有一个服务器端 post-receive
钩子代码片段,它检查名称匹配 release*
的分支是否已被推送到,如果是,则调用 shell 带有分支名称的函数(每个这样的分支一次):
#! /bin/sh
NULL_SHA1=0000000000000000000000000000000000000000
scan()
{
local oldsha newsha fullref shortref
local optype
while read oldsha newsha fullref; do
case $oldsha,$newsha in
$NULL_SHA1,*) optype=create;;
*,$NULL_SHA1) optype=delete;;
*) optype=update;;
esac
case $fullref in
refs/heads/*)
reftype=branch
shortref=${fullref#refs/heads/}
;;
*)
reftype=other
shortref=fullref
;;
esac
case $optype,$reftype,$shortref in
create,branch,release*|update,branch,release*)
do_release $shortref;;
esac
done
}
scan
(以上大部分是样板,我已将其精简为要点)。您将不得不编写 do_release
函数,它可能类似于(完全未经测试):
do_release()
{
local tmpdir=/tmp/build.$$ # or use mktemp -d
# $tmpdir/index is git's index; $tmpdir/t is the work tree
trap "rm -rf $tmpdir; exit 1" 1 2 3 15
rm -rf $tmpdir
mkdir $tmpdir/t
GIT_INDEX_FILE=$tmpdir/index GIT_WORK_TREE=$tmpdir/t git checkout
# now clean out grunt files and make zip archive
(cd $workdir/t; rm -rf grunt; zip ../t.zip .)
# put completed zip archive in export location, name it
# based on the branch name
mv $workdir/t.zip /place/where/zip/files/live/.zip
# clean up temp dir now, and no longer need to clean up
# on signal related abort
rm -rf $tmpdir
trap - 1 2 3 15
}
实际上有一个命令,git archive
。
git archive master -o wizzo-v1.13.0.zip
请参阅 EXAMPLES
部分,您可以 select 路径,为它们添加前缀,通过输出扩展定义自定义后处理,以及一些更小的调整。
另请参阅 ATTRIBUTES
部分:您可以给文件 -- 任意模式,实际上 -- 一个 export-ignore
属性以将它们从存档中排除。
它有更多方便的花花公子,您可以从远程存储库获取档案,扩展任意 git log --pretty=format:
占位符,git 联机帮助页绝对值得您投入任何时间。