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?
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.
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
-d'\n'
part from xargs
as this is an illegal argument (and not needed).
tr '\n' '\0'
and then use the -0
arg to xargs to use NUL as the delimiter.
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
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
--add
, as in git config --add --global core.filemode false
If
git config --global core.filemode false
does not work for you, do it manually:
cd into yourLovelyProject folder
cd into .git folder:
cd .git
edit the config file:
nano config
change true to false
[core]
repositoryformatversion = 0
filemode = true
->
[core]
repositoryformatversion = 0
filemode = false
save, exit, go to upper folder:
cd ..
reinit the git
git init
you are done!
.git/config
, a simple git config core.fileMode false
in the root of your project is enough. If you edit the config file, you're better of removing the directive entirely, so that the global one is picked up.
global
option does exactly the same thing as manually editing .git/config
~/.gitconfig
, and ~/project/.git/config
)
git init
should we set filemode back to true?
git init
returns filemode back to TRUE!
Adding to Greg Hewgill answer (of using core.fileMode
config variable):
You can use --chmod=(-|+)x
option of git update-index (low-level version of "git add") to change execute permissions in the index, from where it would be picked up if you use "git commit" (and not "git commit -a").
You can configure it globally:
git config --global core.filemode false
If the above doesn't work for you, the reason might be your local configuration overrides the global configuration.
Remove your local configuration to make the global configuration take effect:
git config --unset core.filemode
Alternatively, you could change your local configuration to the right value:
git config core.filemode false
git config -l
(list current config - both local and global)
If you have used chmod command already then check the difference of file, It shows previous file mode and current file mode such as:
new mode : 755
old mode : 644
set old mode of all files using below command
sudo chmod 644 .
now set core.fileMode to false in config file either using command or manually.
git config core.fileMode false
then apply chmod command to change the permissions of all files such as
sudo chmod 755 .
and again set core.fileMode to true.
git config core.fileMode true
For best practises don't Keep core.fileMode false always.
For best practises don't Keep core.fileMode false always
what do you mean, you should explain that.
For best practises don't Keep core.fileMode false always.
Some filesystems (FAT for example) don't support file permissions, so the OS will report a default value (766 on my system anyway). In this case, core.filemode
is absolutely necessary in the local config, unless you want to bloat the commit history with unnecessary and unintentional permission changes
core.filemode=false
then git will ignore execute bit changes, no need to change local permissions. Unless you've already added permission changes to the index, in which case you're missing the step where you would need to git add
after you turn off core.filemode
.
By definining the following alias (in ~/.gitconfig) you can easily temporarily disable the fileMode per git command:
[alias]
nfm = "!f(){ git -c core.fileMode=false $@; };f"
When this alias is prefixed to the git command, the file mode changes won't show up with commands that would otherwise show them. For example:
git nfm status
If you want to set filemode to false in config files recursively (including submodules) : find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'
git submodule foreach git config core.fileMode false
Simple solution:
Hit this Simple command in project Folder(it won't remove your original changes) ...it will only remove changes that had been done while you changed project folder permission
command is below:
git config core.fileMode false
Why this all unnecessary file get modified: because you have changed the project folder permissions with commend sudo chmod -R 777 ./yourProjectFolder
when will you check changes what not you did? you found like below while using git diff filename
old mode 100644
new mode 100755
This works for me:
find . -type f -exec chmod a-x {} \;
or reverse, depending on your operating system
find . -type f -exec chmod a+x {} \;
You don't need to change the config file.
Just run:
git diff -G.
if you set : sudo chmod 777 -R
you can run : git config core.fileMode false
you can sée : https://www.w3docs.com/snippets/git/how-to-make-git-ignore-file-mode-changes.html
I have been blocked by this problem for days, and eventually solved it after reading @Daniel Reis answer. But I need to highlight that:
git diff -G.
the trailing dot is not end of sentence, but regex expression that matches everything. You must include this dot!!!
This is a new account that cannot comment. I have to open a new answer.
Again, thanks a lot to Daniel!
Success story sharing
git config --global core.filemode false
you'll only need to do this once for all repos.git config
command writes the setting to the correct config file (.git/config
for just the current repository, or~/.gitconfig
if used with--global
).