246

I've read through a few questions regarding file permissions in Git and I'm still a bit confused. I've got a repo on GitHub forked from another. Post merge, they should be identical. However:

$ git diff --summary origin/epsilon master/epsilon
 mode change 100644 => 100755 ants/dist/sample_bots/csharp/compile.sh
 mode change 100644 => 100755 ants/dist/starter_bots/coffeescript/MyBot.coffee
 mode change 100644 => 100755 ants/dist/starter_bots/coffeescript/ants.coffee
 mode change 100644 => 100755 ants/util/block_test.sh
 mode change 100644 => 100755 manager/mass_skill_update.py
 mode change 100644 => 100755 worker/jailguard.py
 mode change 100644 => 100755 worker/release_stale_jails.py
 mode change 100644 => 100755 worker/start_worker.sh

I've tried changing file permissions, but it does not alter the diff results.

Synesso
  • 37,610
  • 35
  • 136
  • 207

7 Answers7

482

I found the solution of how to change permissions (also) on Windows here: http://blog.lesc.se/2011/11/how-to-change-file-premissions-in-git.html

For example following command adds user execute permission to an arbitrary file:

git update-index --chmod=+x <file>
dedek
  • 7,981
  • 3
  • 38
  • 68
  • 9
    +1: exactly what I needed to make sure the shell scripts I commit from Windows (where I have `core.filemode` set to `false`) actually have the execute bit set. – tomlogic Oct 24 '13 at 22:00
  • In my case I also added a new line to the file, and only then was able to commit – oshai Jul 07 '16 at 18:46
  • 10
    In Windows, using git-bash, I needed a `--add` flag to the execution for some reason: `git update-index --add --chmod=+x `. After this, the file was already in stage with the chmod – Jefferson Quesado Oct 16 '19 at 18:43
  • 1
    Has no effect anymore, neither in git bash nor in cmd.exe prompt. – Ben Mar 16 '20 at 17:14
  • @Ben just tried in cmd, worked like a charm. Maybe you are ignoring file mode? (see answer below) – Erdal G. Feb 27 '21 at 07:35
  • @ErdalG. oh good gracious, I have no idea what issue I was having at that time. I think it was Windows-related, so likely that was part of the issue? I'll need to remember core.filemode if I ever come across it again. – Ben Mar 02 '21 at 19:40
  • 3
    @Ben you also need to remember to not to say things like "Has no effect anymore" without being sure of it – Erdal G. Mar 04 '21 at 07:13
  • Oh I definitely was sure of it at the time. I remember doing "git reset --hard" and still seeing modifications to the file modes. It was driving me bonkers because it was blocking whatever basic git operation I was trying to do at the time. I tried this solution and it did nothing at all. But I cannot for the life of me remember what repository I was working on, what sort of filesystem it was in, or how I eventually solved it. – Ben Mar 04 '21 at 17:16
  • I tried this in the cmd as well as a powershell on Windows 11 and it didn't fix the file permissions. I had to set `core.fileMode` to false (in the project config) as explained in [Corey's answer](https://stackoverflow.com/a/6476550). For me the affected file was the `.gitignore`. – Tim Feb 27 '23 at 15:34
152

From another question here on stackoverflow: How do I make Git ignore file mode (chmod) changes?

First see what core.filemode is set to -

git config core.filemode

Try setting it to false:

git config core.filemode false

From git-config(1):

   core.fileMode
       If false, the executable bit differences between the index and the
       working copy are ignored; useful on broken filesystems like FAT.
       See git-update-index(1). True by default.
Brian Burns
  • 20,575
  • 8
  • 83
  • 77
Corey Henderson
  • 7,239
  • 1
  • 39
  • 43
  • 1
    Thanks. I saw that too. Tried it and it made no difference. – Synesso Jun 25 '11 at 08:04
  • 4
    I had similar problems to the OP and couldn't pull changes no matter how `hard` I tried to reset. This did the trick for me. – Jo-Herman Haugholt Oct 13 '11 at 09:10
  • 15
    [project]/.git/config may contain the same setting and will override ~/.gitconfig. If you're trying to set it globally, make sure it isn't being overridden locally. – Binary Phile Jan 31 '13 at 19:56
  • 6
    I find this is necessary on NTFS as well, sadly. – Marc.2377 Apr 30 '19 at 17:15
  • 3
    That's the answer! – Andrei Surdu Apr 14 '20 at 08:30
  • @Marc.2377 yeah, the trouble is that while NTFS has the concept of execute permissions, it is ... extremely unusual to find a file whose ACL doesn't grant execute permission to whomever is also granted read permission. Like, the only time I remember seeing such a file was when I disabled execute permissions on my copy of spider.exe so I'd stop reflexively starting Spider Solitaire whenever I got slightly bored. – SamB Feb 11 '22 at 00:14
  • This worked for me - I'm using vscode and the weirdly unchangeable shell scripts finally vanished from the list of modified files. – Brian Burns Aug 31 '22 at 16:51
38

Handy one-liner for Git Bash:

find . -name '*.sh' | xargs git update-index --chmod=+x

It will mark all .sh file as executable. After that, you just have to git commit.

Benoit Blanchon
  • 13,364
  • 4
  • 73
  • 81
  • 1
    It is better to avoid using `xargs` (deeper explanation on why can be found [here](https://mywiki.wooledge.org/BadUtils#xargs)). Try instead: `find . -name '*.sh' -type 'f' -exec git update-index --chmod=+x {} +` . This will execute the command for each file that `find` finds. – Bruno Saboia Nov 24 '21 at 16:57
24

If you use Cygwin git (or Linux git, too, I assume), there's a good chance your core.filemode setting has been set at the project level in $projdir/.git/config . I found that I had to do the following to get my Cygwin git and my Windows git to coexist nicely on a Windows filesystem without nonexistent filemode changes showing up all the time:

  • delete the line setting core.filemode in $projdir/.git/config
  • in Windows git, run "git config --global core.filemode false"

This allows my Cygwin git to continue to see filemode changes, which are usually relevant, while instructing the Windows git to ignore the filemode changes it sees, which are usually false positives.

skiphoppy
  • 97,646
  • 72
  • 174
  • 218
20

First check file permissions using below command.

git ls-files --stage

Then change permissions. Here "x" represents execute permissions.

git update-index --chmod=+x 'scriptname.ext'

Now re-verify the permissions.

git ls-files --stage

NB: If you are running Windows and deploying on Linux, be sure the repository contains code with Unix-like line endings. To bulk-convert files, you could try dos2unix.exe, or work in Git Bash.

Lee Goddard
  • 10,680
  • 4
  • 46
  • 63
Sireesh Yarlagadda
  • 12,978
  • 3
  • 74
  • 76
5

I fixed it by changing the file permissions in Ubuntu, commit, push and all OK. Seems it just wouldn't work with msysgit on Windows/NTFS.

Synesso
  • 37,610
  • 35
  • 136
  • 207
  • I cna recommend GitHub for windows. Wonderfull interface and really nice shell, I even made relativly easy ssh key setup and git flow install. – Sangoku Oct 25 '13 at 10:57
0

In my case, I accidentally shifted the shebang line so that

#! /bin/sh

became

   #! /bin/sh

This fails the git-bash permission check. After removing the leading whitespaces, the script becomes executable again.

kakyo
  • 10,460
  • 14
  • 76
  • 140