5

I am the only person involved with this git project. Every time I edit files at my local Ubuntu repository, then push to Bitbucket and pull to my production repository, git changes the edited files to -rwxrwxr-x 775. Apache doesn't like this.

Local system: git version 1.8.1.2 on Ubuntu Linux

Production system: git version 1.7.12 on CentOS/Red Hat Linux

When I fix permissions to 755, then do

git diff

or

git diff -p

It shows nothing.

At my local repository, the permissions are 755 and the files are all owned by haws. At my production repository, all other permissions stay at 755, and all files including contact.php are owned by my username.

At both the local and the production repository, I changed core.filemode as follows in an attempt to stop this behavior,

core.filemode = false

I've had mysteries like this in collaborative projects, so I'd really like to understand what's happening.

  1. What can I do to see git's reason for changing the permissions of this file?
  2. How can I get git to stop changing it?

I have also tried to find the solution here: Prevent Git from changing permissions on pull to no avail.

My Final Solution (thanks to VonC's guidance):

  1. Thanks to VonC's good explanations, I was brave enough to figure out that every time I was logging into my server, my umask was going back to 0002. So I created a user startup script (.bashrc or in my case .bash_profile) at my Linux host that sets

    umask 0022

or using symbolic notation (for a little added value)

umask u=a,g-w,o-w 

or

umask u=a,go-w 

(Allow all permissions for user, disallow write permissions for group and others)

That solved my issue.

  1. I had previously set git config core.sharedRepository true, but that was not my issue, and I removed the setting once the issue was resolved.
Community
  • 1
  • 1
Tom Haws
  • 1,322
  • 1
  • 11
  • 23
  • See the comment on October 16 2009 http://stackoverflow.com/questions/1580596/how-do-i-make-git-ignore-mode-changes-chmod Also it may have to do with the way you are adding the files to the working tree (git add . vs git commit -a) – spuder May 23 '13 at 17:17
  • Turning core.filemode to false is probably not a bad workaround. And maybe it's not a bad standard work flow practice either. Still, I'd like to know why git is not "working as advertised". What am I overlooking? – Tom Haws May 23 '13 at 21:29
  • I suggest mentioning your operating system and git version for better and clearer answers. There are differences here with respect to windows, and non-windows systems. – Arafangion Aug 27 '13 at 06:18
  • Thank you. Doing as you suggested. – Tom Haws Aug 27 '13 at 13:51
  • Also see the question http://stackoverflow.com/questions/10657513/git-always-pulls-files-that-i-cant-edit for more information. – andygavin Aug 28 '13 at 18:39

1 Answers1

8

As mentioned in "Wrong file permission when using git pull in a hook"

Git does not store permissions, apart from the executable bit.
So, on checkout, files are created with the default permissions, which depend on your umask.

In your case: umask 0022 should be set when you are pulling.
(that is what I was mentioning in the answer you saw "Prevent Git from changing permissions on pull")

This assume that you have, in the target repo, a configuration like:

git config core.sharedRepository true

The other solution is mentioned in "How do I share a Git repository with multiple users on a machine?", where you would make sure to pull in a repo initialized like so:

git init --shared=0022

The OP Tom Haws adds in the comments:

Do you know why git at my client's production server is able to pull without having file permission changes even when there is no sharedRepository entry in that repository's config?

Maybe because umask was set by default to 0022 already, meaning that, by default, the git shell inherits the umask of the system.
Changing the umask requires a core.sharedRepository set to true to take it into account instead of taking the umask of the parent process.
That, or because the repo was created with --shared=0022.

To see how an umask can be set (system wide or user-wide), see "How to set system wide umask?"

To check an umask just before a git command (which would inherit its value), simply type:

umask
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1. I set umask to 0022. How do I know that git is not changing that when it pulls? – Tom Haws Aug 27 '13 at 14:09
  • 2. I added the git config core.sharedRepository true. This resolved my issue. I will read about this. Thanks. I'm accepting your answer and hoping you will hang with me on this a bit longer to help me understand what is happening. The reason I am still confused is that I don't understand how sharedRepository applies in this case. Is it because "haws" owns the files at my local server and "jconstru" owns them at the production server? – Tom Haws Aug 27 '13 at 14:15
  • I still don't understand. Why is this not an issue on my client's project where there are three developers all with local Ubuntu repositories pushing and pulling and my umask there is 0022 and git config at the production server says only [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true – Tom Haws Aug 27 '13 at 14:35
  • @TomHaws the idea is that, if `core.sharedRepository` is set to true, then git will respect `umask` when pulling. git doesn't change the umask (but it can ignore it if `core.sharedRepository` is set to `false` or not set at all). – VonC Aug 27 '13 at 14:41
  • Do you know why git at my client's production server is able to pull without having file permission changes even when there is no sharedRepository entry in that repository's config? – Tom Haws Aug 27 '13 at 14:59
  • @TomHaws Maybe because `umask` was set by default to `0022` already (meaning that, by default, the git shell inherits the `umask` of the system. Changing the `umask` requires a `core.sharedRepository` to be set to true to take it into account instead of taking the umask of the parent process). That, or because the repo was created with `--shared=0022`. – VonC Aug 27 '13 at 15:05
  • @TomHaws if my previous comment enough to explain why the client's production server is able to pull without change? Is the `umask` to `0022` by default there? And only `0002` on your local Ubuntu server? – VonC Aug 28 '13 at 15:26
  • Ahh! Now you are revealing to me new things! Thanks a million. Can I give you more bounty? We are getting close. Questions: 1. How do we know the default umask? 2. How do we find out and change the umask that git inherited? – Tom Haws Aug 28 '13 at 15:46
  • @TomHaws I have edited the answer to address those additional questions. – VonC Aug 28 '13 at 18:08
  • I have edited my question to show my final solution you taught me. – Tom Haws Sep 06 '13 at 00:41