现在我们开始学习如何构建一个Git服务器,如何编写自定义的Git钩子(hook)来针对某些事件(比如,通知事件)触发特定的动作以及如何将你的代码发布到网站上。
直 到现在,我们关注的还是作为一个用户如何与Git交互。本文将对Git管理以及如何设计一个灵活的Git基础设施进行讨论。你可能认为这听起来有点像“高 级Git技术”或“只有学霸才能阅读”的委婉说法,但实际上,这些任务只需要你对Git如何工作有一个中级水平的理解,有些情况下还需要一点Linux知 识,而不需要什么高级知识,也不需要任何特别的训练。
共享Git服务器
创建你自己的共享Git服务器相当简单,很多情况下也值得为此努力。它不仅可以确保你总能访问自己的代码,而且便于通过扩展增强Git的功能,这些扩展包括个人Git钩子、无限制数据存储以及持续的集成与部署等。
假如你知道如何使用Git和SSH,那么你已经知道如何创建一个Git服务器了。设计Git的方式,你创建或者克隆一个仓库时,你已经创建了一半服务器。使能SSH访问仓库,并且任何访问你仓库的人都可以使用你的回购协议作为一个新克隆的基础。
但是,会有一个小特设。有些计划你可以构建关于同样数量的精心设计的Git服务器,但是可以具有更好扩展性。
首先是:识别你的用户,包括闲杂与未来的。假如你是唯一用户,那么无需任何改变,但是如果你邀请国外的贡献者了,那么你应该为开发者搭建一个贡献共享系统平台。
假 定你有一个可用的服务器(如果不是,Git无法解决这个问题,但是运行在Raspberry Pi 3 的CentOS将会是一个良好开端),第一步是采用SSH键值授权登录,它比密码登录更加强大,因为它能免疫于蛮力攻击,并且可以避免用户尽可能简单地删 除它们的键值。
在你启用了SSH密钥认证之后,就创建一个 gituser用户。这是一个提供给所有通过了认证的用户的共享用户账号:
$ su -c 'adduser gituser'
然后切换到这个用户,并使用合适的权限创建一个 ~/.ssh 框架。这非常重要,因为如果权限设置太过于随意,你自己针对SSH的防护默认就会失效。
$ su - gituser $ mkdir .ssh && chmod 700 .ssh $ touch .ssh/authorized_keys $ chmod 600 .ssh/authorized_keys
authorized_keys 文件里面有所有你赋予其权限操作你的Git工程的开发者的SSH公共密钥。你的开发者必须创建属于他们自己的SSH密钥并将其中的公共密钥发送给你。要把这些公共密钥复制到gituser的 authorized_keys 文件中去。例如,对于一个叫做Bob的开发者,可以运行这些命令:
$ cat ~/path/to/id_rsa.bob.pub >> \ /home/gituser/.ssh/authorized_keys
当开发者Bob持有能匹配他发送给你的公共密钥的私有密钥时,他就能以gituser访问服务器。
不 过,你并不会真的想让你的开发者访问到服务器,即使只是以gituser用户来进行访问。你想要的是让他们只能访问到Git资源库。因为这个原因,Git 提供了一个受限的shell,恰如其分的将其称为 git-shell、以root用户运行下面的这些命令可以将git-shell添加到你的系统中,并使其成为gituser用户的默认shell:
# grep git-shell /etc/shells || su -c \ "echo `which git-shell` >> /etc/shells" # su -c 'usermod -s git-shell gituser'
现在gituser只能使用SSH来向Git资源库进行推送和拉取操作,而不能访问到一个登陆shell。你应该将你自己加入gituser对应的用户组,在我们的示例服务器中它还是gituser。
例如:
# usermod -a -G gituser seth
剩 下的唯一一个步骤就是创建一个Git资源库。因为不会有人在服务器上跟它进行直接交互(也就是说你不会通过SSH连上服务器然后直接在资源库中进行操 作), 这使其成为了一个基础的资源库。如果你想要把服务器上的资源库用起来,就要将其从它所在的地方克隆到自己的home目录中去。
严格来说,你并不用使其成为一个基础资源库,它还是可以作为一个普通的资源库来操作的。不过,一个基础资源库是没有*工作树(working tree)* (也就是说,不会有分支会处在”checkout“状态)。这很重要,因为远程用户不会被允许向一个活动分支进行推送 (你是不会想在一个”dev“分支工作时突然有人将变更推送到你的工作空间的?)。因为基础资源库不能有活动分支,那就不会有问题发生了。
你可以将资源库放到任何你想要放置的地方, 只要你想赋予权限的用户和组也能访问到它就行了。你不会想将目录存储到一个用户的home目录的,因为这里的权限相当地严格, 而是要放在一个通用共享的位置,例如 /opt or /usr/local/share.
以root用户创建一个基础资源库:
# git init --bare /opt/jupiter.git # chown -R gituser:gituser /opt/jupiter.git # chmod -R 770 /opt/jupiter.git
现在任何已gituser认证的、或者是位于gituser分组的用户都可以读取和写入jupiter.git资源库。你可以在自己本机上试试看:
$ git clone gituser@example.com:/opt/jupiter.git jupiter.clone Cloning into 'jupiter.clone'... Warning: you appear to have cloned an empty repository.
记住:开发有必须让他们的公共SSH密钥导入gituser用户的 authorized_keys 文件, 或者是拥有服务器上面的账户(就像你一样), 那样的话他们就必须是gituser组的成员。
Git钩子
运行你自己的Git服务器带来的一个好处是它提供了Git钩子。Git托管服务有时也提供了一个类似钩子的接 口,但那并不是真正的可以访问文件系统的Git钩子。一个Git钩子是一个脚本,它在Git进程中的某个时刻执行。在一个仓库(repository)接 受一个提交(commit)之前,或者收到一个提交之后,或者接收一个推送(push)之前,或者收到一个推送之后等时刻执行一个钩子。
这个系统很简单:任何可执行的脚本都存放在.git/hooks目录中,使用标准的命名方案,并且在某个指定的时刻执行。脚本执行的时间由名字来决定;pre-push脚本在推送之前执行,post-receive脚本在收到一个提交之后执行,诸如此类。它基本上属于自文档(self-documenting)。
可以使用任何语言编写钩子脚本;如果你能在你的系统上运行某种语言的hello world脚本,那么你就可以使用那门语言来编写Git钩子脚本。默认情况下,Git附带了一些范例,但没有启用。
想要运行一个脚本吗?使用起来很简单。如果你还没有Git仓库的话,首先创建一个。
$ mkdir jupiter $ cd jupiter $ git init .
然后编写一个”hello world” Git钩子。由于在工作中我为了传统支持而使用tcsh,所以我坚持使用它作为我的脚本语言,但你可以自由地选用你喜爱的语言(Bash、Python、Ruby、Perl、Rust、Swift、Go):
$ echo "#\!/bin/tcsh" > .git/hooks/post-commit $ echo "echo 'POST-COMMIT SCRIPT TRIGGERED'" > \ ~/jupiter/.git/hooks/post-commit $ chmod +x ~/jupiter/.git/hooks/post-commit
现在进行测试:
$ echo "hello world" > foo.txt $ git add foo.txt $ git commit -m 'first commit' ! POST-COMMIT SCRIPT TRIGGERED [master (root-commit) c8678e0] first commit 1 file changed, 1 insertion(+) create mode 100644 foo.txt
这就是你的第一个可以正常运行的Git钩子。
著名的推送到web 钩子
一个流行的Git钩子用法是自动推送改变部分到工作生产中的web服务器目录。这是一个伟大构建FTP的方式,保留开发环节的全版本控制,并且整合、自动化发布内容。
如果正确执行,它将会工作运行良好,在某一种程度来说,一直应该做的是考虑如何网络发布。它是不错的。我不知道最初是谁想出这主意的,但是我第一次是从 EMacs和来自IBM公司的Git-mentor、Bill Von Hagen那里听到的。他的文章仍然是对这个过程起决定性作用的介绍:Git 改变分布式Web开发规则。
Git变量
每个Git钩子获取一组不同的Git动作触发它的相关变量。你可能会用到这些变量,也可能用不到。这取决于你所写的作品。 如果你想要的是一个普通的邮件 来通知你,有人推了东西。那么你不需要细节,也不需要脚本,因为你可以套用现有的样板。如果你想在邮件里浏览别人提交的信息和作者,那么对你的脚本要求更 高。
Git钩子并不是用户直接运行的,所以要理解透如何获取这些混乱却重要的信息。事实上,一个Git钩子脚本与其他任何脚本类似,像BASH、 Python、C++或者其他脚本一样的方式接受来自stdin的参数。不同的是,我们不会提供自己入参,所以使用它时要弄清楚你想要的是什么(参数)。
编写一个Git钩子之前,可以进入到你的项目目录.git/hooks查看Git提供的范例。例如,下面是pre-push.sample文件的注释部分:
# $1 -- Name of the remote to which the push is being done # $2 -- URL to which the push is being done # If pushing without using a named remote those arguments will be equal. # # Information about commit is supplied as lines # to the standard input in this form: # <local ref> <local sha1> <remote ref> <remote sha1>
并非所有的范例写的都那么清晰,文档对于什么钩子需要什么变量的说明还有些不足(除非你要阅读Git的源代码),不过若有疑问,你可以通过trials of other users进行更多地了解,或者编写一个简单的脚本,输出$1、$2、$3等。
分支检测范例
我发现在实际的生产中对钩子最常见的需求是针对受影响的分支触发特定的事件。下面这个例子演示了如何解决这样的任务。
首先,Git钩子本身不是版本控制。也就是说,Git不会跟踪它自己的钩子,因为Git钩子是Git的组成部分而不是你的仓库的一部分。因此,Git钩子在监视提交和推送的同时,可能对你的Git服务器上的远程仓库最有意义,而不是作为你的本地仓库的一部分。
我们来编写一个基于post-receive运行的钩子(即,收到一个提交之后)。第一步是识别分支名字:
#!/bin/tcsh foreach arg ( $< ) set argv = ( $arg ) set refname = $1 end
for循环读第一个参数($1),然后再次循环读入第二个参数值($2),接着用第三个参数($3)再次循环。在Bash中有更好的方式:使用read命令,将这些值放入一个数组。但是,这里使用的是tcsh,并且变量顺序是预先定义好的,这样做要安全些。
当有即将提交的refname时,我们可以使用Git来获取可读性的分支名:
set branch = `git rev-parse --symbolic --abbrev-ref $refname` echo $branch #DEBUG
这时我们可以将分支名与基于动作名的关键字进行比较:
if ( "$branch" == "master" ) then echo "Branch detected: master" git \ --work-tree=/path/to/where/you/want/to/copy/stuff/to \ checkout -f $branch || echo "master fail" else if ( "$branch" == "dev" ) then echo "Branch detected: dev" Git \ --work-tree=/path/to/where/you/want/to/copy/stuff/to \ checkout -f $branch || echo "dev fail" else echo "Your push was successful." echo "Private branch detected. No action triggered." endif
相关推荐
通过以上步骤,你已经在自己的计算机上成功建立了Git服务器端,使用Gitblit作为管理工具,实现了远程代码仓库的功能。现在,团队成员可以方便地进行代码版本控制和协同开发。记住,持续学习和实践是提升Git技能的...
在企业环境中,自建git服务器是一项重要的任务,它可以帮助团队高效地进行代码版本控制和协作。下面我们将详细探讨如何在公司内部搭建git服务器,并通过提供的文档和资源来深入理解git的相关知识。 首先,我们需要...
在远程端建立Git仓库是安装配置Git服务器的关键一步。在这个过程中,需要确保远程服务器已经设置了git用户,并切换到该用户下,然后创建仓库文件夹,并设置好仓库的相关配置。 通过这一系列的操作,可以在Linux系统...
1. **安装Git服务器**:在服务器上安装Git,通常使用`sudo apt-get install git`(Ubuntu/Debian)或`yum install git`(CentOS/RHEL)。 2. **初始化仓库**:在服务器上选择合适的位置创建空仓库,使用`git init --...
其中`192.168.71.187`应该替换为你自己的服务器IP地址或域名。 ##### 13. 配置Git的Apache虚拟主机 创建一个名为`git.conf`的配置文件,内容如下: ```ini SetEnv GIT_PROJECT_ROOT /home/git/ SetEnv GIT_...
### CentOS下的Git服务器:Gitosis 安装与配置详解 #### 一、Git与Gitosis简介 Git是一款非常流行的分布式版本控制系统,最初由Linux内核的开发者Linus Torvalds为了更好地管理Linux内核的开发而创建。Git因其高效...
搭建本地Git服务器可以帮助团队在苹果开发项目中实现有效的版本控制和协同工作。Gitlib是一个流行的开源工具,用于管理和托管Git仓库。以下是如何在Windows系统上使用Gitlib搭建本地Git服务器的详细步骤: **第一步...
在Windows操作系统上搭建Git服务器,通常我们会选择使用CopSSH作为SSH服务器组件,因为Git原生并不支持Windows上的SSH服务。本文将详细介绍如何在Windows环境中利用Git和CopSSH来创建一个安全、高效的版本控制系统。...
搭建本地git服务器,便于管理app代码、android app代码、android 系统源代码等各种代码
Git是世界上最流行的分布式版本控制系统,它允许开发人员协作并跟踪代码的更改历史。Git-1.8.4-preview20130916.exe 是一个特定版本...通过实践这些步骤,你可以建立起自己的Git服务器,实现代码的高效管理和团队协作。
### Gitolite构建Git服务器:全面解析与实施指南 #### SSH协议:远程操作Git的核心通道 SSH(Secure Shell)协议是构建Git服务器时确保安全、高效远程读写操作的关键技术。在智能HTTP协议普及前,SSH几乎是进行写...
以下是一份详细的步骤指南,帮助你成功地在Linux上建立Git服务器。 首先,确保你的Linux系统已经安装了Git。通过运行`git --version`命令检查Git是否已经安装。如果未安装,你可以使用`yum install -y git`命令...
1、Git64位资源包 2、gitblit-1.8.0.zip 3、TortoiseGit-2.5.0.0-64bit及汉化包 4、文件对比软件beyondcompare4.1.9.rar(必备) ...5、构建git服务器说明文档《Gitblit搭建及Git协作开发流程参考》
用Java编写的简单git服务器 建立和运行 下载并安装Java开发工具包11的最后一个版本与NPM。 适用于Mac的Java- 适用于Linux的Java- 使用以下命令构建VGit的完整发行版: ./gradlew fullBuild 编译后的发行版位于...
通过以上步骤,我们可以构建一个高效、安全的局域网Git服务器,满足团队内部代码管理和协作的需求。自行搭建服务器不仅可以定制化服务,还能根据团队需求进行扩展和优化,是SOHO环境下开发工作的重要工具。
【Bonobo Git Server服务器】是一种基于.NET框架的开源Git服务器,设计用于在本地环境中搭建团队代码管理服务。它提供了一个用户友好的Web界面,使得团队成员可以方便地进行Git仓库的创建、访问、管理和协作。这个...
现在,你已经在Git服务器上建立了一个裸仓库。任何被授权的用户,现在都可以通过Git协议来访问这个仓库,进行代码的推送和拉取操作。 为了方便管理,你可能还需要设置一个特殊的“钩子”脚本,来自动化某些操作。...
### git服务器安装指南 #### 1. 简介 在Amlogic公司的内部环境中,为了实现团队间的代码共享与协作开发,通常需要设置一个git服务器。git作为一种分布式版本控制系统,能够在本地独立运行,但如果需要与他人共享...
Git服务器Gitolite是搭建基于Git的分布式版本控制系统的一个强大工具,它允许用户轻松地管理和控制对Git仓库的访问权限。Git自身虽然提供了强大的版本控制功能,但对用户权限的管理相对简单,不适合大规模协作环境。...