Categories
chmod git ignore

How do I make Git ignore file mode (chmod) changes?

2674

I have a project in which I have to change the mode of files with chmod to 777 while developing, but which should not change in the main repo.

Git picks up on chmod -R 777 . and marks all files as changed. Is there a way to make Git ignore mode changes that have been made to files?

2

  • 42

    This is helpful when working with git on Windows + Bash on Ubuntu on Windows

    – Elazar

    Jan 5, 2017 at 19:50

  • 9

    For anyone who just wants to ignore permission changes for a specific invocation of git diff, and who therefore does not want to alter their Git configuration files: you can use git diff -G. per Zed’s answer here.

    – user82216

    May 31, 2018 at 14:19


4468

Try:

git config core.fileMode false

From git-config(1):

core.fileMode
    Tells Git if the executable bit of files in the working tree
    is to be honored.

    Some filesystems lose the executable bit when a file that is
    marked as executable is checked out, or checks out a
    non-executable file with executable bit on. git-clone(1)
    or git-init(1) probe the filesystem to see if it handles the 
    executable bit correctly and this variable is automatically
    set as necessary.

    A repository, however, may be on a filesystem that handles
    the filemode correctly, and this variable is set to true when
    created, but later may be made accessible from another
    environment that loses the filemode (e.g. exporting ext4
    via CIFS mount, visiting a Cygwin created repository with Git
    for Windows or Eclipse). In such a case it may be necessary
    to set this variable to false. See git-update-index(1).

    The default is true (when core.filemode is not specified
    in the config file).

The -c flag can be used to set this option for one-off commands:

git -c core.fileMode=false diff

Typing the -c core.fileMode=false can be bothersome and so you can set this flag for all git repos or just for one git repo:

# this will set your the flag for your user for all git repos (modifies `$HOME/.gitconfig`)
git config --global core.fileMode false

# this will set the flag for one git repo (modifies `$current_git_repo/.git/config`)
git config core.fileMode false

Additionally, git clone and git init explicitly set core.fileMode to true in the repo config as discussed in Git global core.fileMode false overridden locally on clone

Warning

core.fileMode is not the best practice and should be used carefully. This setting only covers the executable bit of mode and never the read/write bits. In many cases you think you need this setting because you did something like chmod -R 777, making all your files executable. But in most projects most files don’t need and should not be executable for security reasons.

The proper way to solve this kind of situation is to handle folder and file permission separately, with something like:

find . -type d -exec chmod a+rwx {} \; # Make folders traversable and read/write
find . -type f -exec chmod a+rw {} \;  # Make files read/write

If you do that, you’ll never need to use core.fileMode, except in very rare environment.

40

  • 229

    If you do git config --global core.filemode false you’ll only need to do this once for all repos.

    – Greg

    Oct 21, 2012 at 20:05

  • 20

    this didn’t work for me until I’ve fixed the case it should be fileMode instead of filemode

    – tishma

    Oct 31, 2012 at 10:02

  • 10

    @tishma: Git configuration section and variable names are case insensitive according to the documentation, see the CONFIGURATION FILE section, so if the above didn’t work for you then it was for a different reason.

    Oct 31, 2012 at 18:24

  • 13

    @donquixote: The git config command writes the setting to the correct config file (.git/config for just the current repository, or ~/.gitconfig if used with --global).

    Nov 27, 2013 at 21:15


  • 11

    @zx1986: It doesn’t matter. From git config: “The variable names are case-insensitive, …”

    May 23, 2015 at 7:03

310

undo mode change in working tree:

git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x
git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x

Or in mingw-git

git diff --summary | grep  'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x
git diff --summary | grep  'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x

Or in BSD/macOS

git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | tr '\n' '\0' | xargs -0 chmod -x
git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | tr '\n' '\0' | xargs -0 chmod -x

12

  • 44

    On OS X Lion, omit the -d'\n' part from xargs as this is an illegal argument (and not needed).

    – Pascal

    Jun 16, 2011 at 20:07

  • 12

    You can ignore any errors about “chmod: missing operand after `+x'”

    Jul 8, 2011 at 22:03

  • 5

    is this up to date? I get ‘chmod: too few arguments’ in mingw

    – hammett

    Mar 23, 2012 at 18:18

  • 8

    @Pascal @pimlottc The -d specifies the delimiter to be newline instead of any whitespace. BSD xargs doesn’t have that option, but instead you can pipe the output through tr '\n' '\0' and then use the -0 arg to xargs to use NUL as the delimiter.

    Jun 12, 2013 at 17:42

  • 13

    Cool, the tr thing worked! Here’s the full command for OSX: git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x

    Apr 23, 2015 at 17:47


151

If you want to set this option for all of your repos, use the --global option.

git config --global core.filemode false

If this does not work you are probably using a newer version of git so try the --add option.

git config --add --global core.filemode false

If you run it without the –global option and your working directory is not a repo, you’ll get

error: could not lock config file .git/config: No such file or directory

3

  • 7

    Looks like later GIT uses --add, as in git config --add --global core.filemode false

    – mgaert

    Apr 4, 2013 at 10:56

  • 19

    If the repo’s local config already has filemode=true then changing the global config won’t help as the local config will override the global config. Will have to change local config of each repo of the machine once

    – Rakib

    Jul 9, 2015 at 19:40

  • 5

    PLEASE: Update this answer with syedrakib’s warning! Everything felt insane before I found it, and made perfect sense after.

    – jerclarke

    Mar 1, 2016 at 20:43