服务器上的Git && 分布式Git

《Pro Git》读书笔记

服务器上的Git

一个远程仓库通常只是一个裸仓库(bare repository)— 即一个没有当前工作目录的仓库。因为该仓库仅仅作为合作媒介,不需要从磁碟检查快照;存放的只有 Git 的资料。简单的说,裸仓库就是你专案目录内的 .git 子目录内容,不包含其他资料

协议

Git 可以使用四种主要的协议来传输资料:本地协议(Local),HTTP 协议,SSH(Secure Shell)协议及 Git协议。

本地协议

最基本的就是 本地协议(Local protocol) ,其中的远程版本库就是硬盘内的另一个目录。这常见于团队每一个成员都对一个共享的文件系统(例如一个挂载的 NFS)拥有访问权,或者比较少见的多人共用同一台电脑的情况。后者并不理想,因为你的所有代码版本库如果长存于同一台电脑,更可能发生灾难性的损失。

优点

  • 简单,并且直接使用了现有的文件权限和网络访问权限

缺点:

  • 通常共享文件系统比较难配置,并且比起基本的网络连接访问,这不方便从多个位置访问
  • 在同一个服务器上,如果允许 Git 访问本地硬盘,一般的通过 NFS 访问版本库要比通过 SSH 访问慢。
  • 这个协议并不保护仓库避免意外的损坏。每一个用户都有“远程”目录的完整 shell 权限,没有方法可以阻止他们修改或删除 Git 内部文件和损坏仓库。

HTTP协议

智能” HTTP 协议的运行方式和 SSH 及 Git 协议类似,只是运行在标准的 HTTP/S 端口上并且可以使用各种HTTP 验证机制,这意味着使用起来会比 SSH 协议简单的多,比如可以使用 HTTP 协议的用户名/密码的基础授权,免去设置 SSH 公钥。

哑 HTTP 协议里 web 服务器仅把裸版本库当作普通文件来对待,提供文件服务。哑 HTTP 协议的优美之处在于设置起来简单。基本上,只需要把一个裸版本库放在 HTTP 跟目录,设置一个叫做 post-update 的挂钩就可以了

优点(只关注智能“HTTP”协议):

  • 不同的访问方式只需要一个 URL 以及服务器只在需要授权时提示输入授权信息,这两个简便性让终端用户使用Git 变得非常简单。
  • 可以在 HTTPS 协议上提供只读版本库的服务,如此你在传输数据的时候就可以加密数据;或者,你甚至可以让客户端使用指定的 SSL 证书。
  • HTTP/S 协议被广泛使用,一般的企业防火墙都会允许这些端口的数据通过。

缺点:

  • 在一些服务器上,架设 HTTP/S 协议的服务端会比 SSH 协议的棘手一些

SSH协议

架设 Git 服务器时常用 SSH 协议作为传输协议。因为大多数环境下已经支持通过 SSH 访问 —— 即时没有也比较很容易架设。SSH 协议也是一个验证授权的网络协议;并且,因为其普遍性,架设和使用都很容易。

优点:

  • SSH 架设相对简单 —— SSH 守护进程很常见,多数管理员都有使用经验,并且多数操作系统都包含了它及相关的管理工具。
  • 通过 SSH 访问是安全的 —— 所有传输数据都要经过授权和加密。
  • 与 HTTP/S 协议、Git 协议及本地协议一样,SSH 协议很高效,在传输前也会尽量压缩数据。

缺点:

  • 不能通过他实现匿名访问。即便只要读取数据,使用者也要有通过 SSH 访问你的主机的权限,这使得 SSH 协议不利于开源的项目。

Git协议

包含在 Git 里的一个特殊的守护进程;它监听在一个特定的端口(9418),类似于 SSH服务,但是访问无需任何授权。

优点:

  • Git 协议是 Git 使用的网络传输协议里最快的。

缺点:

  • 缺乏授权机制。把 Git 协议作为访问项目版本库的唯一手段是不可取的

在服务器上搭建Git

SSH连接

如果你有一台所有开发者都可以用 SSH 连接的服务器,架设你的第一个仓库就十分简单了,因为你几乎什么都不用做(正如我们上一节所说的)。如果你想在你的仓库上设置更复杂的访问控制权限,只要使用服务器操作系统的普通的文件系统权限就行了。

如果需要团队里的每个人都对仓库有写权限,又不能给每个人在服务器上建立账户,那么提供 SSH 连接就是唯一的选择了。一下提供几种方法:

  • 第一个就是给团队里的每个人创建账号,这种方法很直接但也很麻烦。或许你不会想要为每个人运行一次 adduser 并且设置临时密码。
  • 第二个办法是在主机上建立一个 git 账户,让每个需要写权限的人发送一个 SSH 公钥,然后将其加入 git 账户的~/.ssh/authorized_keys 文件。这样一来,所有人都将通过 git 账户访问主机。这一点也不会影响提交的数据——访问主机用的身份不会影响提交对象的提交者信息。
  • 另一个办法是让 SSH 服务器通过某个 LDAP 服务,或者其他已经设定好的集中授权机制,来进行授权。只要每个用户可以获得主机的 shell 访问权限,任何 SSH 授权机制你都可视为是有效的。

GitWeb

如果你对项目有读写权限或只读权限,你可能需要建立起一个基于网页的简易查看器。Git 提供了一个叫做GitWeb 的 CGI 脚本来做这项工作

如果你想要查看 GitWeb 如何展示你的项目,并且在服务器上安装了轻量级网络服务器比如 lighttpd 或webrick, Git 提供了一个命令来让你启动一个临时的服务器。在 Linux 系统的电脑上,lighttpd 通常已经安装了,所以你只需要在项目目录里执行 git instaweb 命令即可。

分布式Git

分布式工作流程

在集中式系统中,每个开发者就像是连接在集线器上的节点,彼此的工作方式大体相像。而在 Git 中,每个开发者同时扮演着节点和集线器的角色——也就是说,每个开发者既可以将自己的代码贡献到其他的仓库中,同时也能维护自己的公开仓库,让其他人可以在其基础上工作并贡献代码。

集中式工作流

集中式系统中通常使用的是单点协作模型——集中式工作流。

这意味着如果两个开发者从中心仓库克隆代码下来,同时作了一些修改,那么只有第一个开发者可以顺利地把数据推送回共享服务器。第二个开发者在推送修改之前,必须先将第一个人的工作合并进来,这样才不会覆盖第一个人的修改。

enter description here

集成管理者工作流

Git 允许多个远程仓库存在,使得这样一种工作流成为可能:每个开发者拥有自己仓库的写权限和其他所有人仓库的读权限。这种情形下通常会有个代表‘官方’’项目的权威的仓库。要为这个项目做贡献,你需要从该项目克隆出一个自己的公开仓库,然后将自己的修改推送上去。接着你可以请求官方仓库的维护者拉取更新合并到主项目。维护者可以将你的仓库作为远程仓库添加进来,在本地测试你的变更,将其合并入他们的分支并推送回官方仓库。

这是 GitHub 和 GitLab 等集线器式(hub-based)工具最常用的工作流程。

这么做最主要的优点之一是你可以持续地工作,而主仓库的维护者可以随时拉取你的修改。贡献者不必等待维护者处理完提交的更新——每一方都可以按照自己节奏工作

enter description here

司令官与副官工作流

这其实是多仓库工作流程的变种。一般拥有数百位协作开发者的超大型项目才会用到这样的工作方式,例如著名的 Linux 内核项目。被称为副官(lieutenant)的各个集成管理者分别负责集成项目中的特定部分。所有这些副官头上还有一位称为司令官(dictator)的总集成管理者负责统筹。司令官维护的仓库作为参考仓库,为所有协作者提供他们需要拉取的项目代码。

enter description here

向一个项目贡献

提交准则:

  • 你不会想要把空白错误提交上去
  • 尝试让每一个提交成为一个逻辑上的独立变更集。
  • 最后一件要牢记的事是提交信息。有一个创建优质提交信息的习惯会使 Git 的使用与协作容易的多。

维护项目

在特性分支中工作

如果你想向项目中整合一些新东西,最好将这些尝试局限在特性分支——一种通常用来尝试新东西的临时分支中

应用来自邮件的补丁

如果你通过电子邮件收到了一个需要整合进入项目的补丁,你需要将其应用到特性分支中进行评估。有两种应用该种补丁的方法:使用 git apply,或者使用 git am。

具体详情可以参考这里