这个预提交钩子如何修复尾随空格?

发布于 2024-08-29 18:11:46 字数 848 浏览 11 评论 0原文

这个预提交挂钩<发生了什么/a>?我认为更改文件会导致它们被重新暂存。

#!/bin/sh
#
# A git hook script to find and fix trailing whitespace
# in your commits. Bypass it with the --no-verify option
# to git-commit
#

if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do
    # Fix them!
    sed -i 's/[[:space:]]*$//' "$FILE"
done

# Now we can commit
exit

我认为这个想法是删除此提交涉及的所有文件中的尾随空格。

What is going on in this pre-commit hook? I thought changing files would cause them to be restaged.

#!/bin/sh
#
# A git hook script to find and fix trailing whitespace
# in your commits. Bypass it with the --no-verify option
# to git-commit
#

if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do
    # Fix them!
    sed -i 's/[[:space:]]*$//' "$FILE"
done

# Now we can commit
exit

I think the idea is to remove trailing whitespace in all files this commit touches.

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

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

发布评论

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

评论(3

z祗昰~ 2024-09-05 18:11:47

关键是提交正确的内容,即:

  • 仅提交已阶段(并添加到索引中)的内容
  • 加上预提交挂钩引入的一些修改

第一点是通过 git diff-index

将通过树对象找到的 blob 的内容和模式与当前索引的内容进行比较,并且可以选择忽略磁盘上文件的统计状态。

exec git diff-index --check --cached $against --

使用选项 --cached

根本不考虑磁盘上的文件

任何修改都会被视为新提交的一部分。

您可以查看 commit.c 的来源

static int prepare_to_commit(const char *index_file, const char *prefix,
                 struct wt_status *s)
{
...

    if (!no_verify && run_hook(index_file, "pre-commit", NULL))
        return 0;
...


/*
 * Re-read the index as pre-commit hook could have updated it,
 * and write it out as a tree.  We must do this before we invoke
 * the editor and after we invoke run_status above.
 */
discard_cache();
read_cache_from(index_file);

The key is to commit the right content, that is:

  • only what has been stages (and added to the index)
  • plus some modifications introduced by the pre-commit hook

The first point is achieved through the git diff-index

Compares the content and mode of the blobs found via a tree object with the content of the current index and, optionally ignoring the stat state of the file on disk.

exec git diff-index --check --cached $against --

with the option --cached:

do not consider the on-disk file at all

Any modification is then taken into account to be part of the new commit.

You can look at the source of commit.c:

static int prepare_to_commit(const char *index_file, const char *prefix,
                 struct wt_status *s)
{
...

    if (!no_verify && run_hook(index_file, "pre-commit", NULL))
        return 0;
...


/*
 * Re-read the index as pre-commit hook could have updated it,
 * and write it out as a tree.  We must do this before we invoke
 * the editor and after we invoke run_status above.
 */
discard_cache();
read_cache_from(index_file);
落叶缤纷 2024-09-05 18:11:47

但这是行不通的。我尝试在预提交挂钩结束时执行以下操作:

exec git diff-index --check --cached $against --

但在这些挂钩中所做的更改仍然没有真正提交(至少在 git 1.7.3.4 中)。

如果您确实希望进行更改,则必须明确

git add "$file"

针对在预提交阶段修改的每个文件。

Except that this does not work. I've tried doing the following at the end of my pre-commit hooks:

exec git diff-index --check --cached $against --

but the changes made in those hooks still do not actually get committed (at least in git 1.7.3.4).

If you actually want the changes to go in, you must explicitly

git add "$file"

for each file that you modified during the pre-commit phase.

一城柳絮吹成雪 2024-09-05 18:11:47

可以做到这一点,但需要一个棘手的脚本。

在这里您可以找到相同的问题已解决。在那里,它在每次提交时更新文件版本,而不是颤音空格。它正在全面工作:
https://github.com/addonszz/Galileo/tree/master/githooks

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

此外,它只会更改文件(如果已暂存)。如果该文件未暂存,则它将不会执行任何操作。更准确地说,它打印出每一步正在做什么。

It is possible to do that, but requires a tricky script.

Here you can find the same problem solved. There, it is updating the file version on every commit, instead of trilling spaces. It is fully working:
https://github.com/addonszz/Galileo/tree/master/githooks

Then you just replace the 'Version File Replacement' algorithm on the file 'updateVersion.sh', by your 'Trilling Spaces' algorithm. Maybe you need to change a few things like, remove the branch limitation, because there, the script only runs if you are on the 'develop' branch.

Also, it will only change the file, if is staged. If the file is not staged, then it will do nothing. More precisely, it print out what it is doing on every step.

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