Git挂钩可以自动将文件添加到提交中吗?

我想使用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

这样可以成功将它们添加到存储库中,但不会将它们添加到提交中。 我还尝试过在提交后的钩子中使用最后两个exec行以及进行提交前的检查,但是两者都不好。

Ian Terrell asked 2019-11-07T03:57:41Z
10个解决方案
41 votes

由于git add在预提交中也不适用于我,因此我遵循了mark的想法,即使用.commit文件并将该过程分为提交前和提交后。

这是一些应该易于理解的代码

在预提交中:

  • 触摸文件.commit或其他内容。 (确保将其添加到.gitignore)
#!/bin/sh 
echo 
touch .commit 
exit

在提交后:

如果.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

希望这可以使缺乏bash知识的人更容易遵循mark的想法。

bitluck answered 2019-11-07T03:58:49Z
32 votes

使用预提交钩子可以做您想做的事情。 我们为heroku部署做类似的事情(将coffeescript编译为javascript)。 您的脚本无法正常运行的原因是因为您不正确地使用了exec命令。

从手册页:

exec内置函数用于用新命令替换当前正在运行的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
Jim Garvin answered 2019-11-07T03:59:37Z
9 votes

您可以结合使用提交前脚本和发布后脚本。

在预提交中:

  • 触摸文件.commit或其他内容。 (确保将其添加到.gitignore)

在提交后:

如果.commit存在,则您知道已经进行了提交,但尚未执行后提交。 因此,您可以在此处进行代码生成。 此外,测试.commit以及是否存在:

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

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

如果有人知道更好的方法,我将不知所措,但它似乎目前可以使用。

Mark answered 2019-11-07T04:00:38Z
7 votes
#!/bin/sh
#
#  .git/hooks/pre-commit
#

git add file.xyz

这对我来说很好。这将是当前提交的一部分。

git version 1.7.12.4 (Apple Git-37)

calimarkus answered 2019-11-07T04:01:08Z
7 votes

您可以使用update-index

git update-index --add my_files

rfunduk answered 2019-11-07T04:01:39Z
2 votes

如果文件是自动生成的,并且可以在任何地方生成(暗含了在Git预提交钩子中构建它们的愿望),那么您不应该首先将它们置于源代码控制之下。 您应该仅控制源文件-生成的文件应作为构建脚本的一部分生成。

将生成的文件置于源代码控制之下的唯一原因是,当它需要唯一/特权资源来生成(例如许可程序)时,或者它需要大量的时间来生成时。

添加

来自[http://git-scm.com/docs/githooks]:

pre-commit这个钩子由git调用   提交,并可以绕过   --no-verify选项。 它不带参数,在调用之前   获取建议的提交日志   消息并进行提交。 退出中   此脚本的状态为非零   导致git commit中止。

默认的预提交挂钩   启用,捕获行的引入   尾随空格和中止   找到这样的行时提交。

所有的git commit钩子都被调用   与环境变量   GIT_EDITOR =:如果命令不会   调出编辑器来修改   提交消息。

预提交钩子的目的是在进行提交之前,对工作区的状态和提交内容进行通过/失败检查。 尝试更改提交的内容将不起作用。

我的建议是在构建脚本中添加两个步骤:(1)将构建所有需要生成的过时文件(并将它们添加到工作区中)的步骤,以及(2) 将检查以确保所有生成的文件都是最新的,并返回非零状态代码。 您的Git预提交钩子应该运行第二步。 您的开发人员应经过培训,可以根据需要运行第一步。

Craig Trader answered 2019-11-07T04:02:58Z
2 votes

如何编写一个post-commit脚本来生成文件,然后执行git add my_files; git commit --amend(类似)。

rfunduk answered 2019-11-07T04:03:24Z
1 votes

我有同样的需求,这种方法对我来说非常有效:

#!/bin/sh
files='git diff --cached --name-only'
re="<files of importance>"
if [[ $files =~ $re ]]
then
   echo "Creating files"
   create_my_files && git add my_files
fi

其中“ create_my_files”应该是可执行的,例如,如果它是python文件,则可以将其作为“ python create_my_files && git add my_files”执行

并且是真的,您不需要再次提交就可以进行预提交(这将创建一个无限讨厌的循环:p)

Hassek answered 2019-11-07T04:04:02Z
1 votes

是的,您可以使用git hooks在提交时自动添加生成的文件! 但这需要一个棘手的脚本。

在这里您可以找到解决的问题。 在那里,它将在每次提交时更新文件版本,添加新的修改后的文件,并根据需要修改提交。 它可以正常工作:[https://github.com/evandrocoan/.versioning]

然后,只需用算法替换文件“ updateVersion.sh”上的“版本文件替换”算法即可。 也许您需要更改一些内容,例如删除分支限制,因为在那里,仅当您位于“ develop”分支时,脚本才会运行。

此外,如果已暂存,它将仅更改指定的文件。 如果该文件未暂存,则它将仅执行正常/常规提交。 更准确地说,它可以打印出每个步骤的操作。

我将解释这个技巧。 这很棘手。 在prepare-commit-msg-hook上,它检测是否正在暂存和落实所需的文件。 之后,它将创建一个标志文件,并停止prepare-commit-msg-hook。稍后在提交后挂接上,它检查标志文件是否存在。 如果是,它将修改提交中的文件。

注意,这将创建一个无限循环,因为它将再次调用prepare-commit-msg-hook(正如我们正在修改的那样)。 但是由于标志文件,它不会发生。 当prepare-commit-msg-hook运行并找到标志文件时,它“知道”正在发生的事情。 然后就是删除标志文件,而不再创建它。 这样做,它将阻止提交后挂接再次修改提交,从而使提交永久完成。

user answered 2019-11-07T04:05:02Z
-1 votes

我在预提交挂钩中也遇到了同样的问题。 我正在修改一个文件并提交,但它正在获取以前的文件而不是更新的文件,因此通过在预提交钩子中添加git命令(如下所示)即可解决。

git add $file

注意:$file是要添加的文件。

谢谢,

Saroj Kumar Moharana answered 2019-11-07T04:05:36Z
translate from https://stackoverflow.com:/questions/3284292/can-a-git-hook-automatically-add-files-to-the-commit