setgid bit not preserved by git on new directory i

2019-04-14 10:20发布

I have a bare git repository setup for user fred:

/home/fred/foo.git

I have set the group of every file in foo.git to bar:

$ chown -R fred:bar /home/fred/foo.git

(Note that fred is not a member of group bar)

And I have set the setgid bit on for every directory in foo.git:

$ find foo.git -type d -print0 | xargs -0 chmod g+s

However when fred commits to the git repository, the group is not preserved in some files.

Specifically in the objects directory I see:

foo.git/objects:
drwxrws--- 46 fred bar 4096 Apr  7 23:43 .
drwxrws---  7 fred bar 4096 Apr  6 17:12 ..
drwxrws---  2 fred bar 4096 Apr  6 17:11 07
drwxrws---  2 fred bar 4096 Apr  6 17:11 10
drwxrwx---  2 fred bar 4096 Apr  7 22:14 14  <--- HERE
drwxrws---  2 fred bar 4096 Apr  6 17:11 17

      ^--- HERE

Notice that in objects/14 the setgid bit is not set. So consequently when a new object is added to that directory:

foo.git/objects/14:
drwxrwx---  2 fred bar 4096 Apr  7 22:14 .
drwxrws--- 46 fred bar 4096 Apr  7 23:43 ..
-r--r-----  1 fred fred    2595 Apr  7 22:14 95482f8..9d6bfe21

So now the 95482.. file doesn't have group bar, it has group fred.

I suspect that when fred commited, git created a new directory on-demand called objects/14 to hold a new object, when it did this for some unknown reason the setgid bit on the new 14 directory was not set, even though its parent directory objects has the setgid bit set.

If I try to reproduce this manually:

$ su fred                          # as user fred
$ mkdir test1                      # create test1 dir
$ sudo chgrp bar test1             # set group to bar
$ sudo chmod g+s test1             # set setgid bit
$ ls -l
drwxrwsr-x 2 fred bar 4096 Apr  8 21:33 test1

$ mkdir test1/test2                # create dir test1/test2
$ ls -l
drwxrwsr-x 2 fred bar 4096 Apr  8 21:35 test2

      ^--- HERE

Notice the setgid bit in the new test1/test2 is preserved, so when I...

$ touch test1/test2/test3

The new file is still group bar as expected:

$ ls -l test1/test2
-rw-rw-r-- 1 fred bar 0 Apr  8 21:36 test3

Why doesn't git seem to preserve the setgid bit when it creates new directories in the .git directory?

Is there some git setting I can make to fix this? Or can you explain what is causing this?

1条回答
相关推荐>>
2楼-- · 2019-04-14 11:09

It turns out that when you specify the core.sharedrepository config, git does chmod()s on the files it creates. That way, the result is correct despite filesystem types and mount options, except in your one case where the repository owner isn't a member of the group it's shared with.

That bad result happens because git's chmod() appears to succeed -- you can see it in an strace -- but ignores anything the issuing user isn't authorized to ask for.

So to avoid that weirdity, the thing to do is

git config --unset core.sharedrepository

(or not specify --shared at all on the init) so git doesn't touch the filesystem's default permissions at all. Amusingly enough that makes everything work:

~/sandbox/75276/s$ find ../s.git -ls
12193569    4 drwxrws---   4 jthill   mail         4096 Apr  9 13:52 ../s.git
12193571    4 -rw-rw----   1 jthill   mail           73 Apr  8 20:40 ../s.git/description
12193572    4 -rw-rw----   1 jthill   mail           23 Apr  8 20:40 ../s.git/HEAD
12721086    4 drwxrws---   2 jthill   mail         4096 Apr  9 13:52 ../s.git/objects
12193570    4 drwxrws---   2 jthill   mail         4096 Apr  9 13:52 ../s.git/refs
12193578    4 -rw-rw----   1 jthill   mail          104 Apr  9 13:37 ../s.git/config
~/sandbox/75276/s$ cat ../s.git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
[receive]
        denyNonFastforwards = true
~/sandbox/75276/s$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 198 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/jthill/sandbox/75276/s.git
 * [new branch]      master -> master
~/sandbox/75276/s$ find ../s.git -ls
12193569    4 drwxrws---   4 jthill   mail         4096 Apr  9 13:52 ../s.git
12193571    4 -rw-rw----   1 jthill   mail           73 Apr  8 20:40 ../s.git/description
12193572    4 -rw-rw----   1 jthill   mail           23 Apr  8 20:40 ../s.git/HEAD
12721086    4 drwxrws---   5 jthill   mail         4096 Apr  9 13:53 ../s.git/objects
16777964    4 drwxrwsr-x   2 jthill   mail         4096 Apr  9 13:53 ../s.git/objects/58
16777965    4 -r--r--r--   1 jthill   mail           17 Apr  9 13:53 ../s.git/objects/58/7be6b4c3f93f93c489c0111bba5596147a26cb
16777962    4 drwxrwsr-x   2 jthill   mail         4096 Apr  9 13:53 ../s.git/objects/ab
16777963    4 -r--r--r--   1 jthill   mail           46 Apr  9 13:53 ../s.git/objects/ab/69b4abf3bb84d4e268bd42d84e4a9a5e242bd3
16777960    4 drwxrwsr-x   2 jthill   mail         4096 Apr  9 13:53 ../s.git/objects/81
16777961    4 -r--r--r--   1 jthill   mail          120 Apr  9 13:53 ../s.git/objects/81/210f2df9629e5df5f6dfa0923a2cf72369314d
12193570    4 drwxrws---   3 jthill   mail         4096 Apr  9 13:53 ../s.git/refs
12193573    4 drwxrwsr-x   2 jthill   mail         4096 Apr  9 13:53 ../s.git/refs/heads
12193574    4 -rw-rw-r--   1 jthill   mail           41 Apr  9 13:53 ../s.git/refs/heads/master
12193578    4 -rw-rw----   1 jthill   mail          104 Apr  9 13:37 ../s.git/config
~/sandbox/75276/s$ 
查看更多
登录 后发表回答