Git钩子可以自动添加文件到提交吗?

Ian*_*ell 58 git pre-commit pre-commit-hook githooks

我想使用Git中的预提交或后提交挂钩将自动生成的文件添加到同一提交中,这取决于在该提交中修改的文件.我该怎么做?

我已经尝试过这个作为预先提交的钩子,但没有运气:

#!/bin/sh
files=`git diff --cached --name-status`
re="<files of importance>"
if [[ $files =~ $re ]]
then
  echo "Creating files"
  exec bundle exec create_my_files
  exec git add my_files
  exec git commit --amend -C HEAD
fi
Run Code Online (Sandbox Code Playgroud)

这会成功将它们添加到存储库,但不会将它们添加到提交中.我也尝试在post-commit钩子中使用最后两个exec行以及pre-commit检查,但也没有好处.

小智 41

由于git add在预提交中对我来说也不起作用,因此我遵循了标记使用.commit文件并将进程分为提交前和提交后的想法.

以下是一些易于理解的代码

在预提交中:

  • 触摸文件.commit或其他内容.(务必将其添加到.gitignore)
#!/bin/sh 
echo 
touch .commit 
exit
Run Code Online (Sandbox Code Playgroud)

在提交后:

如果.commit存在,你知道刚刚发生了提交但是提交尚未运行.所以,你可以在这里进行代码生成.另外,测试.commit以及它是否存在:

  • 添加文件
  • commit --amend -C HEAD --no-verify(避免循环)
  • 删除.commit文件
#!/bin/sh
echo
if [ -a .commit ]
    then
    rm .commit
    git add yourfile
    git commit --amend -C HEAD --no-verify
fi
exit
Run Code Online (Sandbox Code Playgroud)

希望这使得那些没有什么bash知识的人更容易遵循马克的想法.

  • 不应该`-a`是`-e`来测试`.commit`是否存在? (4认同)
  • @jcollum:显然,“.commit”文件可以防止无限循环。具体来说,“--no-verify”不会阻止“post-commit”挂钩运行,因此提交后会运行两次:一次是在“.commit”文件存在时运行,然后运行“git commit --” amend ...` 再次触发提交后挂钩,但这次 `.commit` 文件消失,从而结束循环。 (3认同)
  • @AlbertNetymk - 几乎没有区别; `-a` primary是作为KornShell提议引入的,并且已经进入POSIX,它现在只支持向后兼容性.之后添加`-e`以避免将`-a`*primary*与`-a`*binary*运算符混淆. (2认同)
  • 这个方案对我来说很有效,但关键的修改是我必须将“git add”移动到“pre-commit”挂钩,而不是“post-commit”挂钩。我在 macOS 上使用 git 版本 2.25.1。 (2认同)

Jim*_*vin 32

使用预提交挂钩可以做你想做的事.我们为heroku部署做了类似的事情(将coffeescript编译为javascript).您的脚本无法正常工作的原因是您未exec正确使用该命令.

手册页:

exec builtin用于使用新命令替换当前运行的shell进程映像.成功完成后,exec永远不会返回.exec不能在管道内使用.

只有第一个exec命令正在运行.之后,您的脚本基本上终止了.

尝试这样的东西(作为预提交钩子):

#!/bin/sh
files=`git diff --cached --name-status`
re="<files of importance>"
if [[ $files =~ $re ]]
then
  echo "Creating files"
  bundle exec create_my_files
  git add my_files
fi
Run Code Online (Sandbox Code Playgroud)

  • 在git 1.7.10中对我有用。这些文件未添加到提交消息中,但是已提交。看来,提交消息中的“ git status”是在预提交之前生成的。在我看来,这似乎是一个错误,但是我怀疑它是出于某种原因而故意这样做的。您可以做的是在预提交的末尾添加一行,看起来像'git status;。echo -n点击回车继续...; 读'。解决这个问题的方法可能更好,但这对我来说是个快速解决方案。 (3认同)
  • 我有 git 1.8.3.4,并且在预提交挂钩中添加的任何内容似乎都不会暂存,直到下一次提交。 (2认同)
  • `git add`在git 2.1.0版本中不起作用 (2认同)
  • 实际上,我可以在我现在使用的git 2.7.4中确认这个“有效”。在编辑提交消息时,它并不会以这种方式“出现”,但是当您实际提交时,您会看到在预提交钩子过程中添加的文件出现在提交中。 (2认同)

小智 10

您可以使用前提交和后提交脚本的组合.

在预提交中:

  • 触摸文件.commit或其他内容.(务必将其添加到.gitignore)

在提交后:

如果.commit存在,你知道刚刚发生了提交但是提交尚未运行.所以,你可以在这里进行代码生成.另外,测试.commit以及它是否存在:

  • 添加文件
  • commit --ammend -C HEAD --no-verify(避免循环)
  • 删除.commit文件

这大致是我用来在Metastore生成的存储库中存储.metadata文件的过程.

如果有人知道更好的方式,我会全神贯注,但它现在似乎有效.


rfu*_*duk 7

您可以使用update-index

git update-index --add my_files

  • 我不知道@IanTerrell,但我仍然坚持这一点。我尝试了 `git add` 和 `git update-index --add`。在这两种情况下,文件都会添加到存储库中(因此它们会在 *next* 提交中),但不会添加到当前提交中。 (3认同)

cal*_*kus 7

#!/bin/sh
#
#  .git/hooks/pre-commit
#

git add file.xyz
Run Code Online (Sandbox Code Playgroud)

这对我来说很好.它将成为当前提交的一部分.

git version 1.7.12.4 (Apple Git-37)

  • 这也对我有用,除了我需要使用 cd $(git rev-parse --show-toplevel) 更改脚本的工作目录 (2认同)
  • 也为我工作。如果只执行 `git commit`,添加的文件不会出现在自动生成的提交消息中,但无论如何都会添加它们。 (2认同)