Developer
Developer

Reputation: 2895

git clone [email protected]:... auto core.fileMode true

I try setup ignore filemode changes in my repositories

i see in

more .git/config 
[core]
        repositoryformatversion = 0
        filemode = true

i need

core.fileMode=false 

when i clone repository. When i change it localy - there is no changes for push. So when i clone in other system i get

core.fileMode=true

Can I setup this as default for my repository ?

I have

git config --global core.fileMode false

(I use install when docker build and need change permission for editing)

Upvotes: 0

Views: 347

Answers (1)

torek
torek

Reputation: 488463

core.filemode (whether spelled this way or as core.fileMode) is not a user setting and in general you should not change it. There are, however, some special cases where may wish to temporarily change it, to make Git behave technically-incorrectly but usefully, but you need to know exactly what you are doing when you do this.

You mention:

When i change [core.filemode] locally - there is no changes for push

That is because the core.filemode setting is irrelevant to git push. It only matters for how Git resolves the differences, if any, between the modes stored in Git's index and the modes stored in your working tree. The git push operation sends commits to some other Git, and by the time files are stored in a commit, their mode is set forever to whatever was stored in Git's index at commit time. See the long description below.

when i clone in other system ...

The git clone command sets core.filemode based on the behavior of the computer at the time the git clone creates the new empty repository. (Remember that git clone runs git init, and see the long description below.)

(I use install when docker build and need change permission for editing)

Write permissions for files are independent of core.filemode settings.

Long

What core.filemode does is tell Git how your computer behaves. Changing the value stored in core.filemode does not change how your computer behaves, just as drawing a new road on a map does not cause the new road to appear in reality.

Specifically, on Linux systems and similar, some files are called executable and some are called not executable. A not-executable file cannot be run as a command, and an executable file can be (though here the actual content needs to make sense as well). To make a non-executable file become executable on a Linux system, one uses the chmod command (not a Git command):

chmod +x somefile

and now:

./somefile

will try to run the contents of somefile as a command, or series of commands. To mark the same file as not-executable one uses:

chmod -x somefile

and now:

./somefile

just tells you that the file cannot be run (./somefile: Permission denied or similar).

When Git makes a new commit, Git records the executable-ness of each file-to-be-stored-in-the-commit, as indicated by the mode stored in Git's index.1 If you run:

git ls-files --stage

Git will print out, for every file in Git's index, the stored mode. This is always either 100644 ("chmod -x") or 100755 ("chmod +x").2

Some computer file systems, however, either do not store modes at all—this is true for some very old Windows file systems, for instance—or store them erratically. This is why the git config documentation mentions this about core.filemode:

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

When core.filemode is set to true, Git believes that your OS correctly handles the executable bit (as standard Linux file systems do). Hence if, after extracting some commit, a later Git operation discovers that a working tree file has a different executable status than the recorded index mode, Git considers the working-tree file to be "modified". A git add operation will update the stored mode. But when core.filemode is set to false, Git believes that the OS incorrectly turns the executable bit on or off, more or less at random, so after extracting some commit, the working tree file mode is ignored and the index mode is retained.

To change the index mode when using such a system, use git update-index with the --chmod option. Or, you can change core.filemode temporarily. When you do so, Git will start believing the results from lstat system calls—so you need to know how those behave on your computer. After you have done whatever you will do with this, you should generally restore the old core.filemode setting so that Git knows how your computer actually behaves.

(There is one other special case here, and that occurs when you can change how your computer behaves, e.g., with mount-time options.)


1Remember that Git actually builds new commits from what is in Git's index, rather than what is in your working tree. Usually by the time you run git commit you have run the appropriate git add commands that make Git's index match your working tree.

2Symbolic links in Git's index are represented as mode 120000 and gitlinks, which are how submodules work, are represented as mode 160000. The index cannot store directories—entities with mode 040000—which is why Git is unable to store an empty directory, although an empty submodule actually does work for this purpose.

Upvotes: 1

Related Questions