How does this pre-commit hook fix trailing whitespace?

前端 未结 3 1208
没有蜡笔的小新
没有蜡笔的小新 2021-01-21 08:06

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

#!/bin/sh
#
# A git ho         


        
相关标签:
3条回答
  • 2021-01-21 08:09

    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.

    0 讨论(0)
  • 2021-01-21 08:18

    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);
    
    0 讨论(0)
  • 2021-01-21 08:25

    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.

    0 讨论(0)
提交回复
热议问题