本文转载自:http://blog.chinaunix.net/uid-15007890-id-3217101.html
硬件需求:一台linux Ubuntu电脑(虚拟机),在公司局域网内有独立IP,并且保证小组每个人都能ping通;
软件需求:git-core, gitosis, openssh-server, openssh-client
安装git和openssh:
[email protected]:~$ sudo apt-get install git-core
[email protected]:~$ sudo apt-get install openssh-server
[email protected]:~$ sudo apt-get install openssh-client
新加用户git,该用户将作为所有代码仓库和用户权限的管理者:
[email protected]:~$ sudo useradd -m git
为git设置密码:
[email protected]:~$ sudo passwd git
建立一个git仓库的存储点,我放在了/home/prj_git下,并且让除了git以外的用户对此目录无任何权限:
[email protected]:~$ sudo mkdir /home/prj_git
[email protected]:~$ sudo chown git:git /home/prj_git
[email protected]:~$ sudo chmod 700 /home/prj_git
初始化一下服务器的git用户,这一步其实是为了安装gitosis做预备,当然在任何一台机器上使用git,第一次必须要初始化一下,git向来不搞“知名不具”那一套:
[email protected]:~$ git config --global user.name "ly44770"
[email protected]:~$ git config --global user.email "[email protected]"
安装一下python的setup tool, 这个也是为了gitosis做预备:
[email protected]:~$ sudo apt-get install python-setuptools
获得gitosis包:
[email protected]:~$ cd /tmp
[email protected]:/tmp$ git clone git://eagain.net/gitosis.git
[email protected]:/tmp$ cd gitosis
[email protected]:/tmp/gitosis$ sudo python setup.py install
切换到git用户下:
---------------------------
[email protected]:/tmp/gitosis$ su git
默认状态下,gitosis会将git仓库放在git用户的home下,所以我们做一个链接到/home/prj_git
$ ln -s /home/prj_git /home/git/repositories
再次返回到默认用户
$ exit
假如你将作为git服务器的管理员,那么在你的电脑上(另一台pc)生成ssh公钥:
[email protected]:~$ ssh-keygen -t rsa
将公钥拷贝到服务器的/tmp下,并给其他人以读权限:
[email protected]:~$ scp .ssh/id_rsa.pub [email protected]:/tmp
[email protected]‘s password:
id_rsa.pub 100% 390 0.4KB/s 00:00
[email protected]:/tmp/gitosis$ sudo chmod a+r /tmp/id_rsa.pub
让gitosis运行起来:
[email protected]:/tmp/gitosis$ sudo -H -u git gitosis-init < /tmp/id_rsa.pub
Initialized empty Git repository in /home/prj_git/gitosis-admin.git/
Reinitialized existing Git repository in /home/prj_git/gitosis-admin.git/
gitosis的有趣之处在于,它通过一个git仓库来管理配置文件,仓库就放在了/home/prj_git/gitosis-admin.git。我们需要为一个文件加上可执行权限:
[email protected]:/home/git$ sudo passwd root
[email protected]:/home/git$ su
[email protected]:/home/git# cd repositories
[email protected]:/home/git/repositories# cd gitosis-admin.git/
[email protected]:/home/git/repositories/gitosis-admin.git# sudo chmod 755 /home/prj_git/gitosis-admin.git/hooks/post-update
[email protected]:/home/git/repositories/gitosis-admin.git# exit
我们在服务器上新建一个空的项目仓库供大家测试一下,我建了一个叫“teamwork”的仓库。
切换到git用户:
[email protected]:/home/git$ su - git
$ cd /home/prj_git
$ mkdir teamwork.git
$ cd teamwork.git
$ git init --bare
$ exit
在你自己的电脑里,把gitosis-admin.git这个仓库clone下来,这样你就可以以管理员的身份修改配置了。
在你的电脑里:
[email protected]:~/work$ git clone [email protected]:gitosis-admin.git
Initialized empty Git repository in /home/a/work/gitosis-admin/.git/
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 0), reused 5 (delta 0)
Receiving objects: 100% (5/5), done.
[email protected]:~/work$ cd gitosis-admin/
为了测试添加一个新用户:
[email protected]:~/work/gitosis-admin$ sudo useradd -m b
[email protected]:~/work/gitosis-admin$ sudo passwd b
现在把你们team所有人的ssh公钥文件都拿来,按名字命名一下,比如b.pub, lz.pub等,统统拷贝到keydir下:
[email protected]:~/work/gitosis-admin$ su root
[email protected]:/home/a/work/gitosis-admin# cp /home/b/.ssh/id_rsa.pub ./keydir/b.pub
[email protected]:~/work/gitosis-admin$ cp /tmp/lz.pub ./keydir/
[email protected]:/home/a/work/gitosis-admin# exit
修改gitosis.conf文件,我的配置大致如下:
[gitosis]
[group gitosis-admin]
writable = gitosis-admin
members = [email protected]
[group hello]
writable = teamwork
members = [email protected] b
[group hello_ro]
readonly = teamwork
members = lz
这个配置文件表达了如下含义:gitosis-admin组成员有a,该组对gitosis-admin仓库有读写权限;
team组有a,b两个成员,该组对teamwork仓库有读写权限;
team_ro组有lz一个成员,对teamwork仓库有只读权限。
当然目前这些配置文件的修改只是在你的本地,你必须推送到远程的gitserver上才能真正生效。
加入新文件、提交并push到git服务器:
[email protected]:~/work/gitosis-admin$ git add .
[email protected]:~/work/gitosis-admin$ git commit -am "add teamweok prj and users"
[email protected]:~/work/gitosis-admin$ git push origin master
好了,现在服务器就搭建完了,并且有一个空的项目teamwork在服务器上。接下来呢?当然是测试一下,空仓库是不能clone的,所以需要某一个有写权限的人初始化一个版本。就我来做吧,以下是在客户端完成。
[email protected]:~/work$ mkdir teamwork-ori
[email protected]:~/work$ cd teamwork-ori/
[email protected]:~/work/teamwork-ori$ git init
[email protected]:~/work/teamwork-ori$ echo "/*add something*/" > hello
[email protected]:~/work/teamwork-ori$ git add .
[email protected]:~/work/teamwork-ori$ git commit -am "initial version"
[email protected]:~/work/teamwork-ori$ git remote add origin [email protected]:teamwork.git
[email protected]:~/work/teamwork-ori$ git push origin master
到此为止teamwork已经有了一个版本了,team的其他成员只要先clone一下teamwork仓库,就可以任意玩了。
[email protected]:~/work/teamwork-ori$ su b
$ cd /home/b
$ git clone [email protected]:teamwork.git
$ cd teamwork
$ vim hello
$ git add .
$ git commit -am "b add"
$ git push origin master
$ exit
另外:假如你有一个现成的git仓库,想放到gitserver上供team使用(比如你clone了一个官方的kernel仓库,想在内部使用它作为基础仓库),怎么办呢。
首先需要从你的工作仓库中得到一个纯仓库, 比如你的工作目录为~/kernel, 你想导出纯仓库到你的优盘里,然后拷贝到gitserver上去。
$ git clone --bare ~/kernel /media/udisk
然后就拿着优盘,交给gitserver的管理员,让他拷贝到/home/prj_git/下,同时需要配置gitosis相关配置文件哦,这个就不用再说了吧。比如:下载ALSA库:
git clone git://android.git.kernel.org/platform/external/alsa-lib.git
git clone git://android.git.kernel.org/platform/external/alsa-utils.git
生成bare库
git clone --bare alsa-lib alsa-lib.git
git clone --bare alsa-utils alsa-utils.git
4.将bare库移动到git服务器目录
cp alsa-lib.git /home/prj_git
5.注重变更所有者,以获得提交权限。
chown -R git alsa-lib.git
然后就O了,呵呵.
配置web访问方式:
Apache常用命令:
a2dissite gitserver 禁用
a2ensite gitserver 使能
/etc/init.d/apache2 restart 重启
1.apt-get install apache2
2.手动安装gitweb
git clone git://git.kernel.org/pub/scm/git/git.git
cd git
make GITWEB_PROJECTROOT="/home/prj_git" prefix=/usr gitweb/gitweb.cgi
cd gitweb
cp -av git* /home/prj_git/
3.vim /etc/apache2/sites-available/gitserver
ServerName 172.20.146.39
DocumentRoot /home/prj_git
ScriptAlias /cgi-bin/ /home/prj_git
Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
AllowOverride All
order allow,deny
Allow from all
AddHandler cgi-script cgi
DirectoryIndex gitweb.cgi
4.赋予权限,很重要:
chgrp -R www-data /home/prj_git
chmod a+r prj_git
chmod a+x prj_git
mv hooks/post-update.sample hooks/post-update
5.a2ensite gitserver
6./etc/init.d/apache2 restart
匿名访问方式:
git clone http://192.168.1.1/alsa-lib.git
git clone http://192.168.1.1/alsa-utils.git
git访问方式:
git clone [email protected]:alsa-lib.git
Web网页浏览:
http://192.168.1.1
碰到的问题:
1.windows文件命名不区分大小写,而linux支持。这样android源码下载时会出现一下问题。大约有15个文件存在这个问题。
2.库的描述文件在.git文件夹的description文件中。编辑该文件,在gitweb页中就会有description。
3.gitosis库hooks下的post-update不是由post-update.sample重命名过来的,它们不一样。post-update可以更新工作目录,保持与库一致。没有它配置文件是不会更新的。
4.(1)[email protected]:/home/git$ git add .
error: readlink("external/openssl/apps/md4.c"): No such file or directory
error: unable to index file external/openssl/apps/md4.c
fatal: adding files failed
(2)[email protected]/external/openssl# git init
Initialized empty Git repository in /external/openssl/.git/
[email protected]/external/openssl# git add .
error: readlink("apps/md4.c"): No such file or directory
error: unable to index file apps/md4.c
fatal: adding files failed
(3)[email protected]_r2$ rm -Rf .repo
[email protected]_r2$ find . -name ".git" | xargs rm -Rf
Command:
git clone [email protected]:/home/prj_git/gitosis-admin.git
Web:
http://192.168.1.190/cgi-bin/gitweb.cgi
Todo:
How to access in "git clone http://192.168.1.1/alsa-lib.git"
安装配置git daemon
1.安装git daemon
apt-get install git-daemon-run
2.修改配置文件
vi /etc/sv/git-daemon/run
最后一行,修改为:
exec chpst -ugit git daemon –verbose –export-all –base-path=/www/git/repositories/
3.启动服务
/etc/init.d/git-daemon stop
4.查看进程
ps aux|grep git
root 17284 0.0 0.0 116 28 ? Ss 09:16 0:00 runsv git-daemon
gitlog 17285 0.0 0.0 132 48 ? S 09:16 0:00 svlogd -tt /var/log/git-daemon
git
19403 0.0 0.0 48680 1528 ? S 10:39 0:00 git-daemon
–verbose –export-all –base-path=/www/git/repositories/
root 19569 0.0 0.0 6264 732 pts/0 S+ 10:45 0:00 grep git
5.访问仓库
git clone git://192.168.1.9/pbslib.git
通过以上5个步骤,就可以匿名只读访问所有git项目了
6.开通匿名读写权限
vi /etc/sv/git-daemon/run
最后一行,修改为:
exec chpst -ugit git daemon –verbose –enable=receive-pack –export-all –base-path=/www/git/repositories/
7.重启git daemon
/etc/init.d/git-daemon restart
git push如果出现错误
1. errno=Connection refused
2. fatal: The remote end hung up unexpectedly
errno=Connection refused
fatal: The remote end hung up unexpectedly
这是因为git-daemon命令缺少这几个参数:
–enable=upload-pack –enable=upload-archive –enable=receive-pack
我的:
#!/bin/sh
exec 2>&1
echo ‘git-daemon starting.‘
exec chpst -ugit \
/usr/lib/git-core/git-daemon --enable=upload-pack
--enable=upload-archive --enable=receive-pack --verbose --export-all
--base-path=/home/git
git daemon –verbose –export-all –base-path=/home/repo/pub –reuseaddr
for a repo with ‘push’ allowed:
git daemon –verbose –export-all –base-path=/home/repo/pub –reuseaddr –enable=receive-pack
And need to add the following in XX.git/.git/config
[receive]
denyCurrentBranch = ignore
To expose repository:
You
have to either put an empty file called git-daemon-export-ok into the
repository or start git daemon with the “–export-all” option.
允许push,也可以在server端设置如下:(或者前面的git-daemon启动时enable receive-pack)
git config daemon.receivepack true
描述了哪些用户/用户组对于分支/标签具有更新权限的配置文件:
$GIT_DIR/info/allowed_users
$GIT_DIR/info/allowed_groups
多数情况下,我们需要建立一个用户组(起名为 git ),并且将相关的开发者账户添加为该组成员。
在使用Git Push代码到数据仓库时,提示如下错误:
[remote rejected] master -> master (branch is currently checked out)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require ‘git reset –hard’ to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set ‘receive.denyCurrentBranch’ configuration variable to
remote: error: ‘ignore’ or ‘warn’ in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: ‘receive.denyCurrentBranch’ configuration variable to ‘refuse’.
To [email protected]:/var/git.server/…/web
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to ‘[email protected]:/var/git.server/…/web’
这是由于git默认拒绝了push操作,需要进行设置,修改.git/config添加如下代码:
[receive]
denyCurrentBranch = ignore
(当然如果是git –bare init这样建立的仓库,在server端不含有.git目录,当然就不需要的了,也不会遇到上面的错误)。
在初始化远程仓库时最好使用 git –bare init 而不要使用:git init
如
果使用了git init初始化,则远程仓库的目录下,也包含work tree,当本地仓库向远程仓库push时,
如果远程仓库正在push的分支上(如果当时不在push的分支,就没有问题), 那么push后的结果不会反应在work
tree上(而且可能会出现上面的错误), 也即在远程仓库的目录下对应的文件还是之前的内容,必须得使用git reset
–hard才能看到push后的内容.
默认情况下:git daemon使用的是9418端口,可以用过–port参数来制定使用的端口。