我为用户设置了一个裸git存储库:
/home/fred/foo.git
我已将
fred
中每个文件的组设置为foo.git
:$ chown -R fred:bar /home/fred/foo.git
(注意
bar
不是组fred
的成员)我已经为
bar
中的每个目录设置了setgid
位:$ find foo.git -type d -print0 | xargs -0 chmod g+s
但是,当
foo.git
提交到git存储库时,该组不会保留在某些文件中。特别是在
fred
目录中,我看到: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
注意,在
objects
中未设置objects/14
位。因此,当新对象添加到该目录时: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
所以现在
setgid
文件没有group95482..
,它有groupbar
。我怀疑,当提交时,git根据需要创建了一个名为
fred
的新目录来保存一个新对象,当它出于某种未知的原因这样做时,新fred
目录上的objects/14
位没有设置,即使它的父目录setgid
设置了14
位。如果我尝试手动复制:
$ 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
注意,新
objects
中的setgid
位被保留,所以当我…$ touch test1/test2/test3
新文件仍按预期分组
setgid
:$ ls -l test1/test2
-rw-rw-r-- 1 fred bar 0 Apr 8 21:36 test3
为什么当
test1/test2
在bar
目录中创建新目录时,git
似乎没有保留setgid
位?我可以做一些git设置来解决这个问题吗?或者你能解释一下是什么引起的吗?
最佳答案
原来,当您指定core.sharedrepository
配置时,git会对它创建的文件执行chmod()
s操作。这样,不管文件系统类型和挂载选项如何,结果都是正确的,除非您的一个案例中存储库所有者不是与之共享的组的成员。
这种糟糕的结果之所以会发生,是因为git的chmod()
似乎成功了(您可以从一个strace中看到),但忽略了发出消息的用户未经授权请求的任何内容。
所以为了避免这种怪癖,我们要做的就是
git config --unset core.sharedrepository
(或者不指定——在init上完全共享)这样git就根本不会触及文件系统的默认权限。有趣的是,这让一切都运转起来:
~/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$