Issue
Is there any way to test if a file is marked as executable from Windows?
I've found that when I create shell scripts, I need to run git update-index --chmod=+x myfile.sh
to set the executable flag (related docs). I'd like to create a pre-commit hook to check for this flag in the git index, and warn me if it's not present. However, there doesn't seem to be a git query-index
type command to allow me to check if the file's been granted executable permissions.
Git Bash seems to be able to see this, as it shows executable files in green, but I'm not sure how it achieves this.
Solution
I'd like to create a pre-commit hook to check for [executable permission] in the git index, and warn me if it's not present. However, there doesn't seem to be a
git query-index
type command to allow me to check if the file's been granted executable permissions.
To read out the information from Git's index, use git ls-files --stage
. With no arguments, this dumps out the entire index content; with a pathspec (file or directory name, glob expression, etc.), it dumps out those names that match the pathspec.
The first entry on each line is the mode. There are only two valid "file" modes these days,1 namely 100644
and 100755
, so each line that begins with one of these represents a file that will go into the next commit. The 100644
files are the ones that are chmod=-x
and the 100755
files are the ones that are chmod=+x
. Anything that is not one of these two modes is not an ordinary file.
Note that this is only relevant to Git's index settings. Windows file systems use a different security model, which is not very accommodating to Git's execute/no-execute concept. See this SuperUser answer and its comment for some links to Cygwin-related discussions about how Cygwin implement their chmod
.
1In very early Git versions, which are no longer in use, more 100xxx
modes were allowed; the xxx
part was a standard Unix chmod
permission. This was discovered to be a mistake, so now the mode is always either rw-r--r--
(644) or rwxr-xr-x
(755). Any entries that have some other leading bits denote something else: 120000
is a symbolic link, and 160000
is a gitlink. The mode 040000
is reserved for tree objects, but the index doesn't hold such objects. These mode bits mirror the inode format mode bits in Linux, which is why there are these odd gaps.
Answered By - torek Answer Checked By - Marilyn (WPSolving Volunteer)