Each entry in a Git tree stores a mode — a 6-digit octal number — alongside the file's blob hash. Only three modes ever appear:
100644 — normal file (read/write for owner, read for everyone)
100755 — executable file (the +x bit is set)
120000 — symbolic link
040000 — sub-directory (a sub-tree)
Git tracks the executable bit but ignores the rest of the POSIX mode — meaning 644 vs 664 won't show as a diff. To stop tracking the exec bit entirely (helpful on Windows):
git config core.fileMode false
Toggle an existing file's exec bit:
git update-index --chmod=+x scripts/release.sh
git commit -m "chore: mark release.sh executable"
This avoids leaving a non-executable file that breaks CI even though the rename looks clean.