如何将文件添加到 git 预提交挂钩中的索引

发布于 2025-01-08 19:09:52 字数 683 浏览 5 评论 0原文

我四处寻找重复的内容,虽然其中一些具有相似的标题,但我没有发现任何人有与我相同的问题,所以这里是。

我编写了一个在预提交上运行的脚本,并使用 git status --porcelain 的输出来编译项目中已更改的任何 LESS 文件。这部分工作正常。但我希望 .css 文件包含在当前提交中。因此,除了运行编译器之外,我的脚本还运行 git add。这就是事情变得棘手的地方。

文件添加到索引中,但它不是当前提交的索引。因此,如果我修改 style.less,并运行 git commit -a (或手动 git add style.less),编译器应该生成 >style.cssstyle.min.css 并将它们添加到当前提交。但我注意到的行为是仅提交了 style.less,尽管两个 .css 文件已添加到下一次提交的索引中。

所以我的问题是:有没有办法将文件添加到预提交挂钩中的提交,以便它们对该提交生效?请注意,在运行预提交挂钩之前,这两个 .css 文件不会被修改,因此我不能只在此之前添加它们。我还知道我可以以非零状态退出挂钩,因此提交被取消,但文件被添加,但我希望避免这种情况。还有更好的想法吗?

I've looked around for duplicates and while some of them have similar titles, I haven't found anyone having the same issue as I am, so here goes.

I've written a script that runs on pre-commit and uses the output of git status --porcelain to compile any LESS file in my project that has changed. This part works fine. But I want the .css files to be included in the current commit. So in addition to running the compiler, my script runs git add <filename>. And here's where things get tricky.

The file is added to the index, but it's not the index of the current commit. So if I modify style.less, and run git commit -a (or manually git add style.less) the compiler should generate style.css and style.min.css and add them to the current commit. But the behavior I've noticed is only style.less is committed, despite the two .css files being added to the index for the next commit.

So my question is: is there a way to add files to a commit in a pre-commit hook so that they take effect for that commit? Note that before the pre-commit hook is run, those two .css files aren't modified, so I can't just add them before that. I also know I can exit the hook with a non-zero status so the commit is cancelled but the files are added, but I hope to avoid that. Any better ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

︶ ̄淡然 2025-01-15 19:09:52

我无法重现您的问题。我最初的猜测是 GIT_INDEX_FILE 环境变量被您的 pre-commit 挂钩取消设置。然而,当我尝试从 pre-commit 取消设置 GIT_INDEX_FILE 时,我遇到了不同的问题(Git 抱怨 .git/index 被锁定)。

下面是一个示例脚本,显示 Git 按您的预期运行,并且肯定还有其他问题。此脚本初始化一个新的测试存储库,创建一个 pre-commit 钩子来模拟您的钩子的功能,并进行一些测试提交:

#!/bin/sh

# initialize the test repository
rm -rf testrepo
git init testrepo
cd testrepo

# create the pre-commit hook
cat <<\EOF >.git/hooks/pre-commit
#!/bin/sh
git status --porcelain | while IFS= read -r line; do
    # todo: handle renames and deletions of a *.less file
    f=${line#???}
    case ${f} in
        *.less)
            fb=${f%.less}
            echo bar >>"${fb}".css
            echo baz >>"${fb}".min.css
            git add "${fb}".css "${fb}".min.css
            ;;
    esac
done
EOF
chmod +x .git/hooks/pre-commit

# create foo.less, commit it
echo foo >foo.less
git add foo.less
git commit -m "add foo.less"

# modify foo.less, commit it
echo foo2 >>foo.less
git commit -a -m "modify foo.less"

如果您运行 git log -p测试存储库并查看生成的提交,您将看到每当 foo.lessfoo.cssfoo.min.css 都会被修改> 已修改。

这就是为什么我认为你的问题是由更改/取消设置 GIT_INDEX_FILE 环境变量引起的:

当运行 git commit -a 时,Git 会创建一个临时索引文件并使用它来代替默认的 .git/index 创建提交。为了让 git add 之类的操作能够在 pre-commit 挂钩中工作,Git 将 GIT_INDEX_FILE 环境变量设置为临时文件的名称。在运行预提交之前创建的索引。如果你的钩子取消设置GIT_INDEX_FILE,或者将其设置为.git/index,那么钩子中的所有Git操作都将尝试修改原始索引,而不是修改的临时索引。用于生成提交。

但是,临时索引文件也充当原始索引文件的锁。如果钩子尝试修改原始索引,并且临时索引存在,那么 Git 将因错误而中止。

I am unable to reproduce your problem. My initial guess was that the GIT_INDEX_FILE environment variable was being unset by your pre-commit hook. However, when I tried unsetting GIT_INDEX_FILE from pre-commit, I got a different problem (Git complained that .git/index was locked).

Here's an example script showing that Git functions as you expect and that something else must be wrong. This script initializes a new test repository, creates a pre-commit hook that emulates what your hook does, and makes a few test commits:

#!/bin/sh

# initialize the test repository
rm -rf testrepo
git init testrepo
cd testrepo

# create the pre-commit hook
cat <<\EOF >.git/hooks/pre-commit
#!/bin/sh
git status --porcelain | while IFS= read -r line; do
    # todo: handle renames and deletions of a *.less file
    f=${line#???}
    case ${f} in
        *.less)
            fb=${f%.less}
            echo bar >>"${fb}".css
            echo baz >>"${fb}".min.css
            git add "${fb}".css "${fb}".min.css
            ;;
    esac
done
EOF
chmod +x .git/hooks/pre-commit

# create foo.less, commit it
echo foo >foo.less
git add foo.less
git commit -m "add foo.less"

# modify foo.less, commit it
echo foo2 >>foo.less
git commit -a -m "modify foo.less"

If you run git log -p in the test repository and look at the resulting commits, you'll see that foo.css and foo.min.css were modified whenever foo.less was modified.

Here's why I thought your problem was caused by changing/unsetting the GIT_INDEX_FILE environment variable:

When git commit -a is run, Git makes a temporary index file and uses that instead of the default .git/index to create the commit. In order for operations like git add to work from within a pre-commit hook, Git sets the GIT_INDEX_FILE environment variable to the name of the temporary index it created before running pre-commit. If your hook unsets GIT_INDEX_FILE, or sets it to .git/index, then all Git operations from within your hook will try to modify the original index, not the temporary index that is used to generate the commit.

However, the temporary index file also acts as a lock on the original index file. If a hook tries to modify the original index, and the temporary index exists, then Git will abort with an error.

—━☆沉默づ 2025-01-15 19:09:52

我想到你可以将 git 属性“clean”作为更新生成文件的脚本。通常该钩子可以运行脚本来整理源代码,但我认为它可以用于“清理”生成的输出。
当您执行“git add”时会触发此属性,并且您可以让脚本对生成的文件执行另一个“git add”。

It occurs to me that you could have the git attribute 'clean' to be a script which updates the generated files. Normally that hook can run a script to tidy up your source code but I think it could be used to "cleanup" your generated output.
This attribute is triggered when you do 'git add' and you could have the script do another 'git add' on the generated file.

不离久伴 2025-01-15 19:09:52

您可以利用修改最后一次提交的机会。只是一个想法。

You may take advantage of amending the last commit. Just an idea.

茶色山野 2025-01-15 19:09:52

你首先为什么要这样做?您正在尝试将生成的文件包含到版本控制中,无论如何,这通常不是一个好主意。如果您需要在结帐时提供 style.min.css,为什么不能在结帐后在构建步骤中生成它?

Why do you want to do this in the first place? You are trying head to include generated files into version control, which is in general a not-so-good ideas anyway. If you need the style.min.css to be there on checkout, why can't you generate it after checkout in a build step?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文