Why is my Git pre-commit hook not executable by default?

GitGithooks

Git Problem Overview


If you see the accepted answer in: https://stackoverflow.com/questions/8598246/aggregating-and-uglifying-javascript-in-a-git-pre-commit-hook, you'll see that I had to do a chmod +x on my pre-commit hook to get it to work.

Why is this not executable by Git by default?

Git Solutions


Solution 1 - Git

My context - web development Node.js. I needed to add husky functionality, but got an error, probably to the disk access. This helped in my situation:

chmod ug+x .husky/*
chmod ug+x .git/hooks/*

Solution 2 - Git

Because files are not executable by default; they must be set to be executable.

The sample files from a git init are all executable; if it's copied or renamed to a non-sample file, it will retain the original file's x flag.

New files will be created with current defaults. In your case, view those defaults with umask:

$ umask
0022

By default, new files won't be u+x unless explicitly set to be.

Solution 3 - Git

> I had to do a chmod +x on my pre-commit hook to get it to work

The problem is to realize that it was not executable in the first place.
That will be easier with Git 2.15.x/2.16 (Q1 2018)

See commit f805a00 (06 Oct 2017) by Damien MariƩ (mdamien).
(Merged by Junio C Hamano -- gitster -- in commit 130b512, 06 Nov 2017)

> ## run-command: add hint when a hook is ignored

> When an hook is present but the file is not set as executable then git will ignore the hook.
For now this is silent which can be confusing.

> This commit adds this warning to improve the situation:

hint: The 'pre-commit' hook was ignored because it's not set as executable.
hint: You can disable this warning with `git config advice.ignoredHook false`

> To allow the old use-case of enabling/disabling hooks via the executable flag a new setting is introduced: advice.ignoredHook.

Solution 4 - Git

Just as a reference, after making the file executable, if that appears in git file changes because of file mode changes, the following would work: (tried in Ubuntu/Linux)

chmod ug+x .husky/pre-commit # make file executable
git config core.filemode false # to ignore file mode changes

Reference: How do I remove files saying "old mode 100755 new mode 100644" from unstaged changes in Git?

Solution 5 - Git

I had the same symptoms, but a totally different cause:

In addition to setting the right permission bits via chmod +x .git/hooks/pre-commit, please make sure your file system is mounted in a way that allows those changes. This can, e.g., be an issue when you have a dual-boot system where you are working on an ntfs-3g mounted Windows drive under Linux.

You can fix it by changing the default permissions in /etc/fstab or the systemd equivalent.

Solution 6 - Git

Just as an add-on answer, here is the function, you can use for initializing a Git repository, which automatically makes hooks executables; you should put it in .bashrc or a file you source when you start your terminal. The story is below :)

ginit () {
    git init
    gitpath=`git rev-parse --show-superproject-working-tree --show-toplevel | head -1`
    chmod u+x "$gitpath"/.git/hooks/*
    for submodule in "$gitpath"/.git/modules/*; do
        chmod u+x "$submodule"/hooks/*
    done
}

I was annoyed by the same thing as you. I do not want to remember that I have to make all hooks executables every time I initialize a repository. Plus, when you use submodules, their hooks are not in .git/hooks, but in .git/modules/NameOfSubmodule/hooks, and these should be made executables too.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJosh SmithView Question on Stackoverflow
Solution 1 - GitRomanView Answer on Stackoverflow
Solution 2 - GitDave NewtonView Answer on Stackoverflow
Solution 3 - GitVonCView Answer on Stackoverflow
Solution 4 - GitDhaval L.View Answer on Stackoverflow
Solution 5 - GitatoView Answer on Stackoverflow
Solution 6 - GitJakub WagnerView Answer on Stackoverflow