首页 > 代码库 > 基于OS X Server 搭建 Git 仓库

基于OS X Server 搭建 Git 仓库

任务:

# 配置可读取Git仓库
# 配置可写入Git仓库

# 配置 Gitweb

系统环境:

# OS X 10.9.2,系统自带 Apache httpd , 版本 2.2.26 (Unix)
# OS X Server 3.1.1,为了避免Server这个词跟其他语境产生混淆,要是提到了OS X Server就用Server( app)替代
# Xcode 5.1,有了Xcode就有了Git,版本 1.8.5.2

描(tu)述(cao):

为什么要本地搭建Git服务器呢?代码的版本管理、集中管理是必须的,虽然现在写的代码还不是什么大项目,但是将代码有条理的管理起来总是好的;虚拟机里面还跑着3+个系统,Win7,XP都会用到,有了Git服务就可以将虚拟机的Git库推送到主机,不用拷来拷去麻烦;最吸引眼球的是Gitweb,搭建好以后就打开浏览器就可以查看所有代码,Get!
整个配置过程挺纠结的,主要是参考的资料太多、看的太杂,重点没看到反而被绕了个大圈子(很多配置方法包括Git官方Book都能成功的略过各种重要细节,给跪了;当然,我承认我还有很多需要学习的地方)。不过话说回来,当你被各种天花乱坠的教程弄得晕头转向还是解决不了问题的时候,回到官方文档才是王道,虽然是英文的(为什么一开始不看官方文档,一来文档太多,动手之前都不知道该从哪里看起;二来难懂啊!)。
另外就是Server(app)这个软件,没有Server(app)完全可以搭建起环境来,但是为了作死,一定要用Server(app)来与系统进行高度整合,目的只是为了用一下开关而已。这里要注意的就是,Apple官网对Server(app)的描述有这么一句话“它是如此简单易用,以至于你不再需要IT部门”,这句话信息量巨大,你会发现,某些情况下修改好conf配置文件后,再回到Server(app)里面进行某些配置的话,conf文件是会被覆盖重写的,所以要么就单独修改conf文件,要么就在Server配置,当然也不用全部手动配置,呃,发现说不清楚了,文章后面提到再描述吧。


下面开始一步一步在Mac里搭建本地的Git服务器

基本配置
  • 配置 Server(app)

打开Server(app),目前Websites服务的状态是这样的(默认是关闭的,这里截图截晚了,PHP默认也是关闭的)

wKiom1Nw8rSSeBfOAAKdkMaUcgI746.jpg

当前网站列表里有两个默认网站,一个80端口,一个443端口。看见默认网站就想删?好的,开始折腾,最后你发现删不了!修改配置文件也不行,删除后自动又生成了,所以,要意识到现在用的是Server,不是Apache Httpd。不过通过上面是动作有如下收获:

1、httpd服务的配置文件的路径为/Library/Server/Web/Config/apache2/httpd_server_app.conf,打开这个文件

#
# Mac OS X Server App
#
# When Server App is installed, this file is used instead of /etc/apache2/httpd.conf
......


也就是说这个配置文件已经替代了apache的httpd.conf。这里只是说明在Server(app)中配置WEB服务应该到这个地方来改,不要去 /etc/apache2/里面去找配置文件,因为现在我们是在Server(app)中架设网站。对,只是说明而已,其实我们的整个过程都没有修改过这个文件,最多就是查看而已,下面才是需要修改的地方。


2、http服务的网站配置路径为 /Library/Server/Web/Config/apache2/sites,这个目录下面就是之前看到的两个默认网站的配置文件

  • 0000_any_80_.conf 对应80端口的网站(主战场)

  • 0000_any_443_.conf 对应443端口的网站

  • ...

这两个文件还有对应的以 .default 、.prev ,可能还有 .syntaxError 结尾的文件,这按名称就可以知道其文件内容分别是默认配置、上一次配置、出错的配置文件,这就是刚开始说的,如果你之前在conf文件里面填写过参数,然后又回到Server(app)里面调整过参数的话,生效的conf文件就会被重写,那么之前你自己写的配置文件就需要到prev里面找。
其实我想表达的就是,我们可以在Server(app)里面对要创建的网站做一个大概的配置(比如说新建网站),然后就不用理会这里的其他选项,细节内容到conf里面进行修改就可以。

继续下面的操作

回到Server(app),将Websites服务的开关调到ON,在浏览器输入 http://localhost,显示如下内容说明服务正常

wKiom1Nw8tvDGZu6AAIuG3-1HLk771.jpg

查看日志到 Server(app) Logs标签,右侧的左下角选择 Error Log (Server Websites) 查看,跟Apache日志是一致的。

既然默认网站删不掉,那么就在默认80端口网站上架设服务好了:
第一步,选择网站路径
假设网站的根目录用如下文件夹(放GoogleDrive里面是可以备份到网盘~~)
/Volumes/Macintosh/GoogleDrive/Website/

第二步,架设站点
选中Websites列表里面80端口的默认网站,直接双击打开配置窗口,第一行,”Store Site Files In”后面的下拉列表点开,选中other..,弹出对话框选择网站路径 /Volumes/Macintosh/GoogleDrive/Website/,OK!仅此而已,可以点确定了。你会发现我们的网站根目录下自动产生了几个文件,这就是默认的html文件(但是是链接,也就是快捷方式),其他的html文件可以删除,到 /Applications/Server.app/Contents/ServerRoot/usr/share/web/locales/zh_CN.lproj 找到原身 default.html,复制到我们的站点跟目录,习惯性的重命名为 index.html

第三步,修改conf文件(编辑虚拟主机)
sudo vim /Library/Server/Web/Config/apache2/sites/0000_any_80_.conf
注意:这里为了确保配置文件的有效更改,修改配置文件前将Web服务暂停,修改之后再开启服务,即Server(app)里面的OFF/ON开关
(这里配置文件的内容跟Apache是一样的语法)

修改文件内容如下:

<VirtualHost *:80>
#管理员邮箱,要想放上自己的邮箱就填上,可选
ServerAdmin admin@example.com
#网站根路径,第一步的内容
DocumentRoot "/Volumes/Macintosh/GoogleDrive/Website/"
#默认文件
DirectoryIndex index.html
#下面9行保持默认值
CustomLog "/var/log/apache2/access_log" combinedvhost
ErrorLog "/var/log/apache2/error_log"
<IfModule mod_ssl.c>
SSLEngine Off
SSLCipherSuite "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM"
SSLProtocol -ALL +SSLv3 +TLSv1
SSLProxyEngine On
SSLProxyProtocol -ALL +SSLv3 +TLSv1
</IfModule>
#设置站点根目录属性,注意红色部分修改,把 ExecCGI 前面的 - 改为 +,后面架设git服务需要使用CGI
<Directory "/Volumes/Macintosh/GoogleDrive/Website/">
Options All -Indexes +ExecCGI -Includes +MultiViews
AllowOverride All
<IfModule mod_dav.c>
DAV Off
</IfModule>
<IfDefine !WEBSERVICE_ON>
Deny from all
ErrorDocument 403 /customerror/websitesoff403.html
</IfDefine>
</Directory>
</VirtualHost>

开启站点服务,浏览地址 http://localhost 目前站点如下所示,这里只是开始,后面的Gitweb会出现在这里(这个页面完全可以自定义,不过看着好看,暂时留着吧)

wKiom1Nw8xKQ4KWsAAIdESQAQEI716.jpg


  • 配置 Git

这里参考过 Git Book (http://git-scm.com/book/zh)。
第一步,创建Git仓库
架设Git服务你肯定得有个git仓库,仓库跟工作目录不一样,是工作目录下隐藏的 .git 里面的内容。
一切从头开始,先在桌面上创建一个文件夹 library,然后将这个文件夹初始化为git库:

Desktop $ mkdir library
Desktop $ git init library
//参数- - bare用来建立一个裸仓库,当然也可以从一个已经存在的工作目录中clone
Desktop $ git clone - - bare library library.git

得到了这个 library.git 库,看似是一个文件夹,其实他是个git库,而且千万不要把它看做一个文件夹,这是来自404的忠告。

第二步,将Git仓库移到站点目录下
站点根目录为 /Volumes/Macintosh/GoogleDrive/Website/

为了方便管理,在根目录新建一个git文件夹,将刚才的library.git放到里面,现在的结构为 /Volumes/Macintosh/GoogleDrive/Website/git/library.git


第三步,配置站点
基本思路:利用Git针对HTTP协议的CGI程序 git-http-backend 来实现智能的HTTP传输协议。
Git针对HTTP,有哑协议和智能协议两种传输协议(具体说明参见git官方book的Git内部原理 > 传输协议),实际上这里我是参考了《Git权威指南》这本书才知道有这么一件事的。这里采用智能协议,虽然说是这种协议效率不是很高,但本地用,基本不影响,再者,智能协议能够显示百分比。

现在的任务是找到这个 git-http-backend 在哪里。就如刚开始强调的一样,有了Xcode就有个Git,所以你会发现Git的核心程序文件在这里:
/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/
使用 ln 命令,在 /usr/libexec/git-core 创建替身以便引用(快捷方式)
sudo ln -s /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/  /usr/libexec/git-core

基于前面的conf配置文件,继续修改(添加)内容
sudo vim /Library/Server/Web/Config/apache2/sites/0000_any_80_.conf
添加部分如下,#后面的注释可以忽略
# Git Setting
# 设置版本库根目录(为了便于扩展,这里指向的是前面的"git"目录)
SetEnv GIT_PROJECT_ROOT "/Volumes/Macintosh/GoogleDrive/Website/git/"
# 设置所有版本库均可访问,话说是因为默认情况下默认只有版本库目录中存在 git-daemon-export-ok 文件时,该版本库才可以访问
SetEnv GIT_HTTP_EXPORT_ALL
# 设置 ScriptAlias ,有点CGI的意思,引用的正是我们上面的那个替身,可以理解为 git 这个虚拟目录指向 /usr/libexec/git-core/git-http-backend/
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/


第四部,站点目录权限

权限!还是权限!万恶的根源!
还记得我们的站点根目录吗?
/Volumes/Macintosh/GoogleDrive/Website/
现在我们把这个地方当作站点根目录,也就是Apache Httpd服务的一个目录,当我们通过浏览器访问站点的时候,其实是以Apache Httpd的身份在访问Website这个文件夹。为了避免后面的问题,需要把根目录权限设置为755,Git仓库还要支持上传,权限设置为775,问题是这权限给谁呢?别照搬网上的。打开 /Library/Server/Web/Config/apache2/httpd_server_app.conf ,找到以下内容:
User _www
Group _www
说明我们架设的站点是以用户 "_www",组"_www" 的身份在访问,现在知道权限给谁了吧。到站点根目录的上一级,也就是 GoogleDrive 目录运行命令,把整个站点的组改为 _www
GoogleDrive $ sudo chgrp -R _www Website
设置git目录权限为组可写
GoogleDrive $ chmod -R 775 Website/git

第五步,获取与推送
经过上面的努力,现在终于可以测试成果了。
#将当前路径定位到桌面
$ cd ~/Desktop
# 获取Git仓库副本
Desktop $ git clone http://localhost/git/library.git gitt
# 现在桌面上将产生一个 gitt 文件夹(刚开始手动创建的 library 文件夹可以清理掉)
到这一步我们的任务一已经基本完成,创建可读取的Git仓库
# 现在这个 gitt 文件夹就是我们的工作目录,可以在里面随便写点内容用于测试,例如touch一个index文件
Desktop $ cd gitt
gitt $ touch index
# 将index提交
gitt $ git add index
gitt $ git commit -m ’test’
# 将当前库推送到git服务站点,运行push
gitt $ git push origin master
# 此时,不出意外会出现错误提示,查看日志发现如下内容
Service not enabled: ‘receive-pack’
# 这一点我表示某些指南上并没有细说,可能是当时我理解的不够透彻,又折腾许久发现要作如下配置
# 对服务站点的Git库 /Volumes/Macintosh/GoogleDrive/Website/git/library.git 的属性进行修改
git config --local http.receivepack true
# 也就是对 library.git 目录下的 config 文件增加了如下内容,注意排版
[http]
     receivepack = true
# 原理是使用智能HTTP传输协议上传数据的时候,Git 使用 send-pack 和 receive-pack 进程,send-pack 进程运行在客户端,receive-pack运行在服务器端。

现在回到桌面的gitt工作目录,再次推送
gitt $ git push origin master
结尾看到 master -> master’ 则说明推送成功。

现在任务二也基本完成了~


第六步,访问控制
如果只在本地使用Git服务的话,以上的匿名访问方式已经可以达到预期了;但是,对于追求完美主义的强迫症患者,或者身处局域网想保护自己的仓库的话,需要对仓库进行权限限制,这里只涉及简单的权限设置,太复杂的方式以后再折腾~

这种加密方式处于Apache层,跟系统目录神马的没有关系。
使用Apache 的 htpasswd 创建用户信息,将会产生一个文件,把这个文件和apache配置文件放到一个目录下

# 最后面的 ’git’ 字符为自己定义的用户名
Desktop $ sudo htpasswd -m -c /Library/Server/Web/Config/apache2/git-user.htasswd git
# sudo 命令要求你输入当前系统密码,别搞混了,验证通过之后才是htpasswd提示 键入 ‘git’ 用户的密码
New password: (自定义的密码为git)
Re-type new password:

# 现在要加密的是我们的第一个git library,继续编辑conf文件(配置完成后重启站点服务)
sudo vim /Library/Server/Web/Config/apache2/sites/0000_any_80_.conf
# 还是在之前的基础上添加如下内容,Location 标签指向当前站点的相对目录,目前只有一个library仓库,多个仓库就用多个Location标签
## Auth
<Location /git/library.git>
AuthType Basic
AuthName "Git Access"
AuthUserFile /Library/Server/Web/Config/apache2/git-user.htpasswd
Require valid-user
</Location>

这里暂时有个疑问,权限控制在终端里面难道有缓存?多次测试后clone就不需要密码了,用SourceTree这个客户端来clone倒是需要验证用户信息的。


  • 配置GitWeb

我自己在刚开始弄这一步的时候,由于很傻很天真,为了这个gitweb组件还各种下源代码各种编译,后来知道真心的我眼泪掉下来,这货好好的放在xcode里面呢!( ⊙ o ⊙ )
由于后面需要修改cgi文件,所以将Xcode里面的gitweb拷贝出来

sudo cp -r /Applications/Xcode.app/Contents/Developer/usr/share/gitweb /var/www/cgi-bin/


修改站点配置文件,增加如下内容

# Gitweb Setting
     Alias /gitweb /var/www/cgi-bin/gitweb/
     <Directory /var/www/cgi-bin/gitweb/>
          Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
          AddHandler cgi-script cgi
          DirectoryIndex gitweb.cgi
          AllowOverride All
          Order Allow,Deny
          Allow from all
     </Directory>

依然和上一步一样,引用同一个git-user.htpasswd文件对站点进行简单访问限制,这里是对浏览器的访问限制,比较直观,在配置文件里面增加如下内容

<Location /gitweb>
          AuthType Basic
          AuthName "Git Access"
         AuthUserFile /Library/Server/Web/Config/apache2/git-user.htpasswd
          Require valid-user
</Location>


打开浏览器,测试当前配置,要求输入密码,输入验证信息git/git

wKioL1Nw8_ihQZDmAADDSKbvSIw509.jpg

看到如下404提示,说明距离成功已经不远了。

wKiom1Nw9DTAPrmHAAB1qn--uGI126.jpg

打开/var/www/cgi-bin/gitweb/gitweb.cgi这个文件,定位到第686行,即
our $GITWEB_CONFIG_SYSTEM = $ENV{‘GITWEB_CONFIG_SYSTEM‘} || “/etc/gitweb.conf”;


同样的,gitweb的多个配置文件是有顺序的,目前我们只需要在 /etc/gitweb.conf 这个文件里面进行配置就可以,当然也可以定位到其他地方。一般情况下这个文件是不存在的,这里就按照默认到/etc/目录下,新建gitweb.conf文件,作如下编辑

注:projectroot 参数指向站点的git目录,不要指向library.git,不然就404了;GIT 参数跟前面保持一致,指向/usr/libexec/git-core/git,前面那个是目录,所以结尾带斜杠,后面的是指向了git这个文件
# path to git projects (<project>.git)
$projectroot = "/Volumes/Macintosh/GoogleDrive/Website/git/";
# Git bin root
$GIT = "/usr/libexec/git-core/git";


配置好路径之后,刷新页面即可看到项目列表。


如果项目路径中有中文字符,点击浏览的时候可能会看不到,解决方法如下:

把gitweb.cgi中所有 file_name=>”$basedir$t->{‘name’}” 替换为 file_name=>”$basedir” . to_utf8($t->{‘name’}) 即可。

引用自:http://blog.mylover.cn/2014/01/关于gitweb中中文文件名乱码及代码高亮的问题

需要注意的是,替换的时候核对一下字符是不是全部匹配,不出意外应该是要替换9个地方。


另外localhost带地球那个页面,也就是index.html那个文件,可以自己修改,加入Giteweb的链接,这是html的内容,作相应修改就可以了。

wKiom1Nw9H2zR0-cAAFTYtjtVtQ521.jpg


PS: 从EverNote里面复制出来的笔记,尽量保持版面整齐,越到后面写的越赶了,主要是时间拖的太久,要是能给同样在纠结这个东西的人提供一点小建议那就很欣慰了。


本文出自 “坚持治疗” 博客,请务必保留此出处http://liongmagezi.blog.51cto.com/2848085/1410154