git仓库是多人协作使用的,可以基于很多种协议,例如http、git以及ssh等。ssh最为安全方便,配置起来也比较容易,但是权限控制是一个问题,比如下面的场景由两个用户st都给一个仓库贡献代码,那么如果通过ssh协议clone/push的话,会在git仓库的服务端新创建一些文件,主要是objects下面(refs下面文件也会做修改),这些文件的属主和属组就是你这个用户创建一个文件默认的属主和属组,参考下面命令和输入
- [steven@localhost demo.git]$ tree -L 2
- .
- |-- branches
- |-- config
- |-- description
- |-- HEAD
- |-- hooks
- | |-- applypatch-msg.sample
- | |-- .......
- | `-- update.sample
- |-- info
- | `-- exclude
- |-- objects
- | |-- 10
- | |-- 1e
- | |-- ......
- `-- refs
- |-- heads
- `-- tags
- [steven@localhost demo.git]$ ls -l objects/
- 总用量 160
- drwxrwxr-x. 2 steven steven 4096 10月 28 19:37 10
- drwxrwxr-x. 2 steven steven 4096 10月 29 18:12 1e
创建的这些目录的属性一般都是775(允许本用户和与本用户处在同一个组的用户修改)或者755(只允许自己修改),当然不能打开其他用户的写权限,那么这就存在一个问题,某用户创建的文件,别的用户就修改不了了,然后git在多人使用过程中又有这样的需求。那么这个问题就可以通过修改用户的默认属组来解决,具体方案如下:
我们创建一个git组,当然也可以同时创建这个用户,因为我打算把git仓库就放在/home/git下面,所以就直接用useradd创建git用户(组)
- # useradd git
对于已经有的账户,我们用usermod -g更改账户的主属组
- $ su
- # usermod -g git steven
- [steven@localhost demo.git]$ touch /tmp/test
- [steven@localhost demo.git]$ ls -l /tmp/test
- -rw-r--r--. 1 steven git 0 10月 31 17:44 /tmp/test
对于新建的账户,直接用useradd -g在添加用户的时候指定
- $ su
- # useradd -g git nicholas
另外,还要确认git目录的写权限
- $ su
- # chmod 770 /home/git
- # chmod g+w objects/
- <pre name="code" class="plain"># chmod g+w refs/</pre>
还要打开git一个很重要的参数sharedRepository,可以参考文章 Sharing your git repository
- [core]
- repositoryformatversion = 0
- filemode = true
- bare = true
- 修改前
- =================================
- 修改后
- [core]
- repositoryformatversion = 0
- filemode = true
- bare = true
- sharedRepository = 1
加这个参数的目的是git在objects目录下创建的目录的属性由
drwxr-xr-x 变成 drwxrwsr-x
注意组权限多了个w,但是r变成s了,这个是因为git通过setgid bit更改这个目录属性(chmod g+s),作用在目录上的setgid可让在该目录下创建的文件继承该目录的组属性,可以参考wikipedia关于setuid, setgid的介绍。
至此便可做到让多个人给仓库推送代码了。
如果那个兄弟先看了这个文章悔恨自己在建用户的时候没有考虑主属组,或者用户太多一个个改主属组,而代码目录权限都可以放开的话,那么可以将/home/git目录的权限放开,让所有用户都可以读写,同时在目录上加上setgit bit - sudo chmod g+s /home/git即可。
更多git协同仓库可参考:
http://www.jedi.be/blog/2009/05/06/8-ways-to-share-your-git-repository/