我想自动复制特定目录中的文件,并在用户输入git commit后暂存这些文件。我尝试了pre-commit钩子,做了复制的工作,并添加了git add .然而,这些阶段并不影响提交本身,我得到的消息是,没有什么可提交的。当用户运行git add的时候,有没有办法运行脚本来实现staging hook?
git commit
git add .
6psbrbz91#
不幸的是,没有git add操作的钩子,只有https://git-scm.com/book/it/v2/Customizing-Git-Git-Hooks官方文档中列出的(客户端)钩子:
git add
vfhzx4xs2#
当你运行git commit时,Git准备提交Git的 index 中的文件。它不会提交工作树中的文件。当运行git add时,Git会将一个工作树文件复制到Git的索引中。这将弹出旧副本(如果存在旧副本)并放入新副本。Git索引中的文件是以一种特殊的形式存储的,适合于存储在提交中:这些都是压缩的,而且重要的是,因为Git将每个文件存储在 every commit-pre-de-duplicated中,所以如果这个文件的副本与任何现有提交中的任何文件的任何副本相匹配,它已经被删除了。(这意味着Git索引中的文件对你来说是无用的。这就是为什么在工作树中有同一个文件的可用版本的原因--至少在您更改它之前是这样。)现在,如果你从一个预提交钩子运行git add *,这 * 可以 * 工作,有时。但有时候,索引不止一个。当有多个索引时--在预提交钩子中,您很难检测到这种情况--运行git add不会有任何好处:它可能影响 next 索引,或者可能影响将被丢弃的临时索引。无论如何,结果都是不好的。这意味着,除非你沉浸在Git更深层次的魔力中,并且可以检测到特殊的索引情况,否则你应该 * 永远不要在预提交钩子中使用git add *。如果你想在提交前运行git add,那么就这样做:运行git add,然后运行git commit。例如,您可以编写一个脚本来执行您需要执行的任何操作,然后运行git add,然后运行git commit。运行此脚本 * 而不是 * git commit。这将是一个更安全的方式来实现你正在努力实现的目标。正如Marek R在评论中所建议的那样,这看起来确实像是XY problem的案例。正如LeGEC answered和我在上面建议的那样,使用脚本似乎是解决真实的问题的方法。
6tqwzwtp3#
从您的评论:我感觉你正在手工做一些git专门设计的东西(结合了两个来源的变化)(git merge已经有了很多特性)。举例来说:我不会考虑重新实现文件重命名检测或差异协调。它肯定会有更多的bug,并且比git内置特性测试得更少。请考虑将该应用程序的两个版本存储在同一个repo的两个分支中,并使用git merge将它们组合在一起。看起来你只是想运行一个脚本:
git
git merge
./update-vendor-files.sh
字符串该脚本将使用git,但是,如果我错了,请纠正我,我认为对于开发人员来说,知道他应该在需要时运行这个特定的操作,而不是试图在任何git add或git commit操作上自动触发它,并不会那么麻烦。如果你想要一个更git y的方式来调用这个脚本:
git-update-vendor-files
PATH
你现在可以运行:
git update-vendor-files
型
3条答案
按热度按时间6psbrbz91#
不幸的是,没有
git add
操作的钩子,只有https://git-scm.com/book/it/v2/Customizing-Git-Git-Hooks官方文档中列出的(客户端)钩子:vfhzx4xs2#
当你运行
git commit
时,Git准备提交Git的 index 中的文件。它不会提交工作树中的文件。当运行
git add
时,Git会将一个工作树文件复制到Git的索引中。这将弹出旧副本(如果存在旧副本)并放入新副本。Git索引中的文件是以一种特殊的形式存储的,适合于存储在提交中:这些都是压缩的,而且重要的是,因为Git将每个文件存储在 every commit-pre-de-duplicated中,所以如果这个文件的副本与任何现有提交中的任何文件的任何副本相匹配,它已经被删除了。(这意味着Git索引中的文件对你来说是无用的。这就是为什么在工作树中有同一个文件的可用版本的原因--至少在您更改它之前是这样。)现在,如果你从一个预提交钩子运行
git add
*,这 * 可以 * 工作,有时。但有时候,索引不止一个。当有多个索引时--在预提交钩子中,您很难检测到这种情况--运行git add
不会有任何好处:它可能影响 next 索引,或者可能影响将被丢弃的临时索引。无论如何,结果都是不好的。这意味着,除非你沉浸在Git更深层次的魔力中,并且可以检测到特殊的索引情况,否则你应该 * 永远不要在预提交钩子中使用
git add
*。如果你想在提交前运行git add
,那么就这样做:运行git add
,然后运行git commit
。例如,您可以编写一个脚本来执行您需要执行的任何操作,然后运行
git add
,然后运行git commit
。运行此脚本 * 而不是 *git commit
。这将是一个更安全的方式来实现你正在努力实现的目标。正如Marek R在评论中所建议的那样,这看起来确实像是XY problem的案例。正如LeGEC answered和我在上面建议的那样,使用脚本似乎是解决真实的问题的方法。
6tqwzwtp3#
从您的评论:我感觉你正在手工做一些
git
专门设计的东西(结合了两个来源的变化)(git merge
已经有了很多特性)。举例来说:我不会考虑重新实现文件重命名检测或差异协调。它肯定会有更多的bug,并且比
git
内置特性测试得更少。请考虑将该应用程序的两个版本存储在同一个repo的两个分支中,并使用
git merge
将它们组合在一起。看起来你只是想运行一个脚本:
字符串
该脚本将使用
git
,但是,如果我错了,请纠正我,我认为对于开发人员来说,知道他应该在需要时运行这个特定的操作,而不是试图在任何git add
或git commit
操作上自动触发它,并不会那么麻烦。如果你想要一个更
git
y的方式来调用这个脚本:git-update-vendor-files
,PATH
上你现在可以运行:
型