Make Shell Script Committed to Git Executable

Git Logo

Posted on May 9, 2016 in Development

You wrote a shell script (script.sh), say for a database backup or to regularly remove old files, and committed and pushed it to your Git repository. You go to your server, do git pull to pull the latest commit and try to execute the script with ./script.sh. Uh, oh, Permission denied, the script won’t run. Ah, no problem, you think, I’ll just change the permissions on the file with chmod. You do that, the script runs, all is peachy. Or so you think.

Next time you push another code update into your repo and then do another git pull, you’ll get this error:

error: Your local changes to the following files would be overwritten by merge: script.sh 
Please, commit your changes or stash them before you can merge.

But I didn’t change the code on the server, you say. No, you didn’t, but you changed the executable permissions on the file which is something that Git keeps track off. You can resolve the above error by resetting the repo clone to the latest commit:

git fetch origin master 
git reset --hard FETCH_HEAD

Great, the error goes away, git pull works as before, but when you try to execute the script you realize you’re getting the Permission denied again – resetting the clone also reset the file permissions and made the script non-executable again.

Since you don’t want to be repeatedly changing the file permissions every time you update your code, what’s the solution?

As I mentioned above, whether the executable bit is on or off is something that Git tracks, so we need to make sure that we flag the file as executable when committing it to the repo in the first place. On your local machine, where you’re writing the code and committing it to the repo, do:

# Stage the script.sh file
git add script.sh 
# Flag it as executable
git update-index --chmod=+x script.sh
# Commit the change
git commit -m "Make script.sh executable."
# Push the commit
git push

Then go to your remote (server), do git pull and try to execute the script. The permissions should be properly set and the script should run without any issues.

Similarly, if you later wanted to remove the executable permission from the file, you would do

git update-index --chmod=-x script.sh

followed by commit and push.

Enjoyed this post? Share it with others.
Share on email
Email
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

Responses (4)

  1. Niels Kristian Jensen
    September 23, 2019 at 5:27 pm · Reply

    I used this to fix all files in a repo:

    git ls-files “*.sh” | xargs git update-index –add –chmod=+x
    git ls-files “*.exe” | xargs git update-index –add –chmod=+x

    • Richard
      September 23, 2019 at 5:31 pm ·

      Great, thanks for sharing, Niels.

  2. Shiplu Mokaddim
    October 8, 2020 at 6:37 pm · Reply

    If this command seems hard to remember

    git update-index –chmod=-x script.sh

    You can do it in usual way.

    chmod -x script.sh
    git add script.sh
    git commit script -m “mark script non-executable”
    git push

  3. Richard
    October 8, 2020 at 9:19 pm · Reply

    Yup, that should work. Thank you for sharing 🙂

Leave a reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.