Git Is Not Ignoring File Permission Changes

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

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`)
# WARNING: this will be override by local config, fileMode value is automatically selected with latest version of git.
# This mean that if git detect your current filesystem is compatible it will set local core.fileMode to true when you clone or init a repository.
# Tool like cygwin emulation will be detected as compatible and so your local setting WILL BE SET to true no matter what you set in global setting.
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.

Git is not ignoring file mode changes (chmod), why?

Local config overrides global config settings

The diff output in the question indicates that the local git config has filemode set to true. This is probably expected behavior since the default config created for a repo defines this:

-> git init
Initialized empty Git repository in /tmp/foo/.git/
-> cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true

Changing the global config for filemode does not affect this, and so in fact git config --global core.filemode false doesn't do anything because this is always overridden locally.

Therefore, to change the filemode for this repo, change the local config:

$ git config core.filemode false
$ git config core.filemode
false

Given this question/answer there's a possibility it is supposed to work, although it didn't for me.

Git is not ignoring file permission changes

Existing repositories typically are not affected by your changing the global setting.

From git-config(1):

git config will only ever change one file at a time.

Creating a new repo (git init) puts an explicit filemode line in the newly created local .git/config file; even when the global ~/.gitconfig file has no such line (in which case the hard-coded default value true will be used). Changing the global configuration afterwards will not change that; it will only affect subsequent git-inits.

With thanks to @jeremyclarke for his valuable comment on this answer:

PLEASE add a second warning to this answer, stating that the global setting won't be applied to existing repos! For each repo you need to run the local command (or it seems "git init" has the same effect). This will affect pretty much everyone and can be extremely confusing (esp. when you first interact with a second repo and have no idea why the global setting isn't working when it worked on the first repo, where you ran both the global and local versions of the setting change.)

Git repo default ignore files permissions

Git ignores all permission bits other than the executable bit
(In other words, file and directory entries of git's tree objects have a permission mask of either 755 or 644 -- nothing else).
core.fileMode is only about the executable bit. You usually want those executable bits honored, except on some weird filesystems, in which case the user should turn core.fileMode off by themselves.

From git help config:

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 an 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).

Can I make git diff ignore permission changes

Use the -G<regex> option ("Look for differences whose patch text contains added/removed lines that match <regex>.") searching for any changes at all - i.e. .. Permissions-only changes don't match this, so they are ignored.

So: git diff -G.

Show git diff, ignoring file permission changes?

This will tell git to ignore permissions:

git config core.filemode false

to filter them in result of diff but not ignore them

git filter-branch -f --tree-filter 'find * -type f | xargs chmod 644 ' -- --all

MIstakenly changed file permissions in a working git repo

The only file permissions Git does track is whether something is executable or not. If you haven’t made a change on the executable bit, then there will be no permission change in your commit and others will not be affected by it.

The file permissions will stay active within your local working directory though, so you should be aware of that. It is possible that certain actions (e.g. checking out a different branch) may or may not overwrite the file permissions on those files individually again in the check-out process.

How to ignore not changed files to git commit in PhpStorm

Also, i noticed, that the files were with a modified permission, so I exclude they with command
git config core.filemode false



Related Topics



Leave a reply



Submit