47

Our workflow is develop on a local machine, commit the changes to a central repository, then check out the branch of that repository that we need.

The problem is that Git changes ownership and even file permissions of the files that it checks out, depending on the user making the checkout. A direct result of this is that our CSS files become unreadable after a checkout, as Git changes the file ownership to the person who did the Git pull in the webroot.

Example:

  • Before git pull: style.css owned by user_a:group_a
  • After git pull: style.css owned by user_b:user_b

I want to keep ownership as user_a:group_a. I don't want to have to log in every time one of my team has made a change to the files, and change the ownership back to the original configuration.

How do other people deal with this? How do you deal with repositories used by multiple users. We have suphp on our system and cannot take it off.

Simon
  • 31,675
  • 9
  • 80
  • 92
Shiro
  • 811
  • 1
  • 7
  • 12
  • http://stackoverflow.com/questions/2517339/git-how-to-recover-the-file-permissions-git-thinks-the-file-should-be – wojciii Jan 28 '13 at 07:13
  • possible duplicate of [Git is changing my file's permissions when I push to server](http://stackoverflow.com/questions/11230171/git-is-changing-my-files-permissions-when-i-push-to-server) – eis Jan 28 '13 at 07:14
  • 8
    Git is not a deployment tool. This comes back in the fact that it doesn't store complete permissions. Use a proper deployment tool that has support for things like setting permissions. – Ikke Jan 28 '13 at 07:21

5 Answers5

41

Git does not change file permissions or ownership. It's just that it (mostly) doesn't store it either, it doesn't exist in your repo, so they get changed to whatever your user has. Just like with any file creation.

Git supports two permission sets: executable bit on and executable bit off. Nothing else. Ownership information is not stored at all.

See this thread - "If you want specific permissions, you'll need to do it manually."

There are some solutions suggested: you can use a separate tool to do it for you, use a proper combination of user account and umask to set them properly by default or write a git hook yourself to do it. A hook would've to be installed on the user doing the checkout.

Like @ikke said in the comments, Git is not really a deployment tool and should not be used as such. It is a version control system for source code.

Community
  • 1
  • 1
eis
  • 51,991
  • 13
  • 150
  • 199
  • What do you recommend for a deployment method? Anything that does not require signing up for 3rd party services? ```scp``` with sym links? – zeros-and-ones Jan 23 '17 at 20:04
  • @zeros-and-ones well, it depends what you're deploying. either doing it through scripting: ansible, salt, capistrano, dandelion..or a CI tool such as gocd, jenkins, deploybot, buildbot, bamboo or similar. or trigger maven tooling, or or. there are plenty of options depending on the use case. – eis Jan 23 '17 at 20:44
  • thx! deploying web apps mostly lamp stacks. just started looking into ansible via ```deploy.serverforhackers.com``` as a resource. like you mention there are soo many names out there hard to know where to start. – zeros-and-ones Jan 23 '17 at 20:57
15

For me, the best solution was creation of a shell script that fixes the permissions. For example:

.git/hooks/post-checkout:

#!/bin/sh
chmod +x  tools/*

Btw, checkout is not the only case when git does mess with permissions, it's also when you pull. I handle that with .git/hooks/post-merge hook.

Ideally, you can create a shell script that fixes permissions somewhere in your repo (e.g. tools/fixpermissions.sh), and call it in both hooks. Don't forget to change the permissions for that file manually ;)

#!/bin/sh
chmod a+x tools/fixpermissions.sh
tools/fixpermissions.sh
tishma
  • 1,855
  • 1
  • 21
  • 43
  • Downside to this is that hooks are not a part of the repo and must hence be created manually. It's possible though to minimize the hook setup effort as described here: http://stackoverflow.com/questions/3462955/putting-git-hooks-into-repository – tishma Aug 15 '13 at 12:50
  • 1
    Additionally, I needed to make the hook executable by running: `chmod ug+x .git/hooks/post-merge` – Robert Lujo Apr 11 '14 at 15:26
  • 1
    since you're only adding the executable bit, that information you actually can store in git. – eis Apr 20 '16 at 10:40
  • @eis you can't because .git dir itself is not under git. – tishma Aug 26 '16 at 08:50
  • @ArthurAraújo post-receive hook is executed on the server after receiving a push, so it definitely does not apply to the problem in question. – tishma Aug 26 '16 at 08:53
  • @tishma but `tools/*` is – eis Sep 28 '16 at 10:48
  • @eis sure, and your comment looked like a response to RobertLujo's one (hook executable bit). ;) – tishma Oct 03 '16 at 07:17
3

The easiest solution is to just run git as user_a.

Chronial
  • 66,706
  • 14
  • 93
  • 99
1

Alternatively you can set a default permission for the folder in question like so: https://unix.stackexchange.com/questions/1314/how-to-set-default-file-permissions-for-all-folders-files-in-a-directory

Community
  • 1
  • 1
andrepo
  • 71
  • 1
  • 2
0

I often run a

git checkout -f file.xml

... on a versioned file.xml with world-write permissions, as I continually modify it and want to return it to the normal state.

But that resets the permissions. A slightly longer version:

git show HEAD:./file.xml > ./file.xml

Just resets the content.

Calpau
  • 921
  • 10
  • 21