Automatically apply "git update-index --chmod=+x" to executable files

GitExecutableFile Permissions

Git Problem Overview


I frequently add bash scripts to my Git repository, and the scripts have executable permissions in the Linux filesystem prior to the git add. But after pushing the added files to a remote repository and pulling in another location, the files show up with non-executable permissions. There seem to be two ways to correct the problem:

  1. chmod u+x $script 
    git commit -am "fixing the script permissions... again..."
    
  2. git update-index --chmod=+x $script
    

Instead of fixing up the permissions every time, is there a way to have Git simply look at the file permissions on the script during git add, recognize "Hey, this here is an executable file!" and add it to the repository with the executable permissions directly?

Git Solutions


Solution 1 - Git

git 2.9.X/2.10 (Q3 2016) brings chmod to git add itself!

See commit 4e55ed3 (31 May 2016) by Edward Thomson (ethomson).
Helped-by: Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit c8b080a, 06 Jul 2016)

> ## add: add --chmod=+x / --chmod=-x options

> The executable bit will not be detected (and therefore will not be set) for paths in a repository with core.filemode set to false, though the users may still wish to add files as executable for compatibility with other users who do have core.filemode functionality.
For example, Windows users adding shell scripts may wish to add them as executable for compatibility with users on non-Windows.

> Although this can be done with a plumbing command (git update-index --add --chmod=+x foo), teaching the git-add command allows users to set a file executable with a command that they're already familiar with.

You can see the origin of this new feature in "How to create file execute mode permissions in Git on Windows?" (Feb. 2011)

Solution 2 - Git

There are several ways to do that.

  1. Git aliases
  2. Bash aliases
  3. Or even combine bash and git aliases

  1. Git aliases

    You can always use bash within your git alias.

    • Open your git config:

      vim ~/.gitconfig

    • Add an aliases section to it (if one does not exist):

        [alias]
            addscr = !sh -c 'if [[ ${0: -3} == ".sh" ]]; then git update-index --chmod=+x $0; git add $0'
      
  2. Bash aliases

    • Edit your bash profile file:

      vim ~/.bashrc

    • Add this at the end of the file:

        function gitadd(){
            if [[ ${1: -3} == ".sh" ]]
                then git update-index --chmod=+x $1
            fi
            git add $1
         }
         alias gitadd='gitadd'
      
  3. Combine git and bash aliases

    • Edit your bash profile file:

      vim ~/.bashrc

    • Add this to the end of the file:

        function checkShellFile(){
            return ${1: -3} == ".sh"
        }
        alias gitadd='checkShellFile ? git addsrcipt "$1" : && git add "$1"'
      
    • Edit your git config file:

      vim ~/.gitconfig

    • Add an aliases section to it (if one does not exist):

        [alias]
            addscript = !sh -c 'git update-index --chmod=+x $0 && git add $0'
      

None of the above has been tested

Solution 3 - Git

Here is a script to automatically apply git update-index --chmod+x to executable files:

for f in `find . -name '*.sh' -o -regex './s?bin/[^/]+' -o -regex './usr/sbin/[^/]+' -o -regex './usr/lib/[^/]+' `;do
 ( cd `dirname $f` && git update-index --chmod=+x  `basename $f` )
done 

Solution 4 - Git

A solution without fancy bash scripting:

  1. Set fileMode = true in your .git/config file (or by running git config core.filemode true as others have pointed out)
  2. Change the executable bit on the file's permissions and commit this change. ( chmod u+x $script as you pointed out). You only have to do this once.
  3. Push to the remote

The next time you pull from there, git will set the committed executable bit on the file. I also had similar problems, this solved them.

fileMode = true tells git to track the only thing about permissions it can: the executable bit. This means that changes to the executable bit will be recognized by git as changes in the working tree and those changes will be stored in the repo with your next commit.

Once you committed the desired executable bit you can also reset your fileMode to false so next time git won't bother you with such changes when you don't want to commit them.

Solution 5 - Git

I don't think this can be done on the git add command, but you might be able to run a script just right after you run the git commit command, but before the commit is actually created.

Take a look at the pre-commit hook.

http://git-scm.com/book/en/Customizing-Git-Git-Hooks

Basically just create a file in your .git/hooks/ folder called pre-commit. (There should be samples already in your hooks folder, rename them to remove the ".sample" at the end to activate one.)

Theres a gotcha. Make sure your script runs git stash -q first so that your working on the actual staged versions of files.

Solution 6 - Git

I just added thru' Tortoise Git folder update. Right click on all files and update the execute permission checkbox to true and commit/push with message. Git Command line add/commit should also work.

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
QuestionByron HawkinsView Question on Stackoverflow
Solution 1 - GitVonCView Answer on Stackoverflow
Solution 2 - GitPassTeTView Answer on Stackoverflow
Solution 3 - Gitl0panView Answer on Stackoverflow
Solution 4 - GitA. SallaiView Answer on Stackoverflow
Solution 5 - GiteddiemoyaView Answer on Stackoverflow
Solution 6 - GitSmart CoderView Answer on Stackoverflow