Skip to content

Commit

Permalink
refector: part4: remove spaces, add line wraps
Browse files Browse the repository at this point in the history
Signed-off-by: Jiang Xin <[email protected]>
  • Loading branch information
jiangxin committed Aug 6, 2012
1 parent a29481c commit 397c430
Show file tree
Hide file tree
Showing 11 changed files with 1,650 additions and 782 deletions.
3 changes: 1 addition & 2 deletions 03-git-harmony/020-conflict.rst
Original file line number Diff line number Diff line change
Expand Up @@ -893,8 +893,7 @@ kdiff3下方的窗口是合并后文件的编辑窗口。如图16-6所示,点
Unpacking objects: 100% (2/2), done.
From file:///path/to/repos/shared
7f7bb5e..615c1ff master -> origin/master
CONFLICT (rename/rename): Rename "doc/README.txt"->"README" in branch "HEAD" rename "doc/README.txt"->"readme.txt" in "615c1ffaa41b2798a5685
4259caeeb1020c51721"
CONFLICT (rename/rename): Rename "doc/README.txt"->"README" in branch "HEAD" rename "doc/README.txt"->"readme.txt" in "615c1ffaa41b2798a56854259caeeb1020c51721"
Automatic merge failed; fix conflicts and then commit the result.

因为两个用户同时更改了同一文件的文件名并且改成了不同的名字,于是引发冲突。\
Expand Down
14 changes: 9 additions & 5 deletions 03-git-harmony/030-git-tag.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ Git里程碑
里程碑可以使用\ :command:`git tag`\ 命令来显示,里程碑还可以在其他命令的\
输出中出现,下面分别对这些命令加以介绍。

**1. 命令\ :command:`git tag`\ **
1. 命令\ :command:`git tag`
-----------------------------

不带任何参数执行\ :command:`git tag`\ 命令,即可显示当前版本库的里程碑列表。

Expand Down Expand Up @@ -108,7 +109,8 @@ Git里程碑
jx/v2.2
jx/v2.3

**2. 命令\ :command:`git log`\ **
2. 命令\ :command:`git log`
-----------------------------

在查看日志时使用参数\ ``--decorate``\ 可以看到提交对应的里程碑及其他引用。

Expand All @@ -118,7 +120,8 @@ Git里程碑
3e6070e (HEAD, tag: jx/v1.0, origin/master, origin/HEAD, master) Show version.
75346b3 Hello world initialized.

**3. 命令\ :command:`git describe`\ **
3. 命令\ :command:`git describe`
-----------------------------------

使用命令\ :command:`git describe`\ 将提交显示为一个易记的名称。这个易记\
的名称来自于建立在该提交上的里程碑,若该提交没有里程碑则使用该提交历史版\
Expand All @@ -134,7 +137,7 @@ Git里程碑
jx/v2.2

* 若提交没有对应的里程碑,但是在其祖先版本上建有里程碑,则使用类似\
``<tag>-<num>-g<commit>``\ 的格式显示。
``<tag>-<num>-g<commit>``\ 的格式显示。

其中\ ``<tag>``\ 是最接近的祖先提交的里程碑名字,\ ``<num>``\ 是该里程碑\
和提交之间的距离,\ ``<commit>``\ 是该提交的精简提交ID。
Expand Down Expand Up @@ -162,7 +165,8 @@ Git里程碑
命令\ :command:`git describe`\ 是非常有用的命令,可以将该命令的输出用作\
软件的版本号。在之前曾经演示过这个应用,马上还会看到。

**4. 命令\ :command:`git name-rev`\ **
4. 命令\ :command:`git name-rev`
-----------------------------------

命令\ :command:`git name-rev`\ \ :command:`git describe`\ 类似,会显示\
提交ID及其对应的一个引用。默认优先使用分支名,除非使用\
Expand Down
17 changes: 7 additions & 10 deletions 03-git-harmony/040-git-branch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,8 @@ Hello World开发计划

* 第一个问题是:帮助信息中出现文字错误。本应该写为“--help”却写成了“-help”。

* 第二个问题是:当执行\ ``hello-world``\ 的程序,提供带空格的用户名时,
问候语中显示的是不完整的用户名。
* 第二个问题是:当执行\ ``hello-world``\ 的程序,提供带空格的用户名时,\
问候语中显示的是不完整的用户名。

例如执行\ :command:`./hello Jiang Xin`\ ,本应该输出“\ ``Hi, Jiang Xin.``\ ”,\
却只输出了“\ ``Hi, Jiang.``\ ”。
Expand Down Expand Up @@ -1156,7 +1156,7 @@ user1推送的用getopt进行命令行解析相关代码。如果基于\ ``maste
| 49 uname = argv[optind]; | 48 p = &argv[optind]; |
| 50 } | 49 } |
| 51 | 50 |
| 52 if (uname == NULL) { | 51 if (p == NULL || *p == NULL) { |
| 52 if (uname == NULL) { | 51 if (p == NULL || *p == NULL) { |
| 53 ======= | |
| 54 char **p = NULL; | |
| 55 | |
Expand Down Expand Up @@ -1279,15 +1279,12 @@ user1推送的用getopt进行命令行解析相关代码。如果基于\ ``maste

$ git log --oneline -2 --stat jx/v1.0-i18n
ade873c Translate for Chinese.
src/locale/zh_CN/LC_MESSAGES/helloworld.po | 30 +++++++++++++++++
++++------
src/locale/zh_CN/LC_MESSAGES/helloworld.po | 30 +++++++++++++++++++++------
1 files changed, 23 insertions(+), 7 deletions(-)
0831248 Add I18N support.
src/Makefile | 21 +++++++++++-
src/locale/helloworld.pot | 46 +++++++++++++++++
+++++++++++
src/locale/zh_CN/LC_MESSAGES/helloworld.po | 46 +++++++++++++++++
+++++++++++
src/locale/helloworld.pot | 46 ++++++++++++++++++++++++++++
src/locale/zh_CN/LC_MESSAGES/helloworld.po | 46 ++++++++++++++++++++++++++++
src/main.c | 18 ++++++++--
4 files changed, 125 insertions(+), 6 deletions(-)

Expand Down Expand Up @@ -1623,7 +1620,7 @@ user1调用\ ``getopt``\ 对命令行参数解析进行的代码重构。图18-7

现在需要将\ ``user2/i18n``\ 分支的提交合并到主线\ ``master``\ 中。实际上\
不需要在\ ``master``\ 分支上再执行繁琐的合并操作,而是可以直接用推送操作\
—— 用本地的\ ``user2/i18n``\ 分支直接更新远程版本库的\ ``master``\ 分支。
——用本地的\ ``user2/i18n``\ 分支直接更新远程版本库的\ ``master``\ 分支。

::

Expand Down
94 changes: 71 additions & 23 deletions 04-git-model/010-central-model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
集中式协同模型
===============

可以像集中式版本控制系统那样使用 Git,在一个大家都可以访问到的服务器上架设 Git 服务器,每个人从该服务器克隆代码,本地提交推送到服务器上。如图21-1所示。
可以像集中式版本控制系统那样使用Git,在一个大家都可以访问到的服务器上架\
设Git服务器,每个人从该服务器克隆代码,本地提交推送到服务器上。如图21-1\
所示。


.. figure:: /images/git-model/central-model.png
Expand All @@ -13,36 +15,56 @@
图21-1:集中式协同模型


回忆一下在使用 Subversion 等集中式版本控制系统时,对服务器管理上的要求:
回忆一下在使用Subversion等集中式版本控制系统时,对服务器管理上的要求:

* 只允许拥有帐号的用户访问版本库。

* 甚至只允许用户访问版本库中的某些路径,其他路径不能访问。

* 特定目录只允许特定用户执行写操作。
* 服务器可以通过钩子实现特殊功能,如对 commit log 的检查,数据镜像等。

对于这些需求,Git 大部分都能支持,甚至能够做到更多:
* 服务器可以通过钩子实现特殊功能,如对提交说明(commit log)的检查,\
数据镜像等。

对于这些需求,Git大部分都能支持,甚至能够做到更多:

* 能够设置谁能够访问版本库,谁不能访问版本库。

* 具有更为丰富的写操作授权。可以限制哪些分支不允许写,哪些路径不允许写。

* 可以设置谁可以创建新的分支。

* 可以设置谁可以创建新的版本库。

* 可以设置谁可以强制更新。

* 服务器端同样支持钩子脚本。

但是也要承认,在“读授权”上 Git 做不到很精细,这是分布式版本控制系统的机制使然。按模块分解 Git 版本库,并结合后面介绍的多版本库协同解决方案可以克服 Git 读授权的局限。
但是也要承认,在“读授权”上Git做不到很精细,这是分布式版本控制系统的机制\
使然。按模块分解Git版本库,并结合后面介绍的多版本库协同解决方案可以克服\
Git读授权的局限。

* Git不支持对版本库读取的精确授权,只能是非零即壹的授权。即或者能够读取\
一个版本库的全部,或者什么也读不到。

* 因为Git的提交是一个整体,提交中包含了完整目录树(tree)的哈希,因此完\
整性不容破坏。

* Git 不支持对版本库读取的精确授权,只能是非零即壹的授权。即或者能够读取一个版本库的全部,或者什么也读不到。
* 因为 Git 的提交是一个整体,提交中包含了完整目录树(tree)的哈希,因此完整性不容破坏。
* Git 是分布式版本控制系统,如果允许不完整的克隆,那么本地就是截然不同的版本库,在向服务器推送的时候,会被拒绝或者产生新的分支。
* Git是分布式版本控制系统,如果允许不完整的克隆,那么本地就是截然不同的\
版本库,在向服务器推送的时候,会被拒绝或者产生新的分支。

**用 Gitolite 架设集中式的 Git 服务器**
**用Gitolite架设集中式的Git服务器**

对于集中式的工作模型的核心就是架设集中式的 Git 服务器,而且尽量能够满足前面提到的对授权和版本库管理上的需求。在本书第5篇介绍服务器部署的时候,会介绍用 Gitolite 架设 Git 服务器,可以实现集中式协同模型对版本库授权和管理上的要求。
对于集中式的工作模型的核心就是架设集中式的Git服务器,而且尽量能够满足前\
面提到的对授权和版本库管理上的需求。在本书第5篇介绍服务器部署的时候,会\
介绍用Gitolite架设Git服务器,可以实现集中式协同模型对版本库授权和管理上\
的要求。

使用集中协同模型
-----------------

对于简单的代码修改,可以像传统集中式版本控制系统(Subversion)中那样工作,参照图21-2所示的工作流程图。
对于简单的代码修改,可以像传统集中式版本控制系统(Subversion)中那样工作,\
参照图21-2所示的工作流程图。


.. figure:: /images/git-model/central-model-workflow-1.png
Expand All @@ -52,32 +74,58 @@

但是对于复杂的修改(代码重构/增加复杂功能),这个工作模式就有些不合适了。

第一个问题是:很容易将不成熟代码带入共享的版本库,破坏共享版本库相应分支的代码稳定性。例如破坏编译、破坏每日集成。这是因为开发者克隆版本库后,直接工作在缺省的跟踪分支上,当不小心执行 `git push` 命令,就会将自己的提交推送到服务器上。
第一个问题是:很容易将不成熟代码带入共享的版本库,破坏共享版本库相应分支\
的代码稳定性。例如破坏编译、破坏每日集成。这是因为开发者克隆版本库后,直\
接工作在缺省的跟踪分支上,当不小心执行\ :command:`git push`\ 命令,就会\
将自己的提交推送到服务器上。

为了避免上面的问题,开发者可能会延迟推送,例如在新功能定制的整个过程(一个月)只在本地提交,而不向服务器推送,这样产生更严重的问题:数据丢失。开发者可能因为操作系统感染病毒,或者不小心的目录删除,或者硬盘故障导致工作成果的彻底丢失,这对个人和团队来说都是灾难。

解决这个问题的方法也很简单,就是在本地创建本地分支(功能分支),并且同时在服务器端(共享版本库)也创建自己独享的功能分支。本地提交推送到共享版本库的自己独享的分支上。当开发完成之后,将功能分支合并到主线上,推送到共享版本库,完成开发。当然如果该特性分支不再需要时需要作些清理工作。参见图21-3所示的工作流程图。
为了避免上面的问题,开发者可能会延迟推送,例如在新功能定制的整个过程(一\
个月)只在本地提交,而不向服务器推送,这样产生更严重的问题:数据丢失。开\
发者可能因为操作系统感染病毒,或者不小心的目录删除,或者硬盘故障导致工作\
成果的彻底丢失,这对个人和团队来说都是灾难。

解决这个问题的方法也很简单,就是在本地创建本地分支(功能分支),并且同时\
在服务器端(共享版本库)也创建自己独享的功能分支。本地提交推送到共享版本\
库的自己独享的分支上。当开发完成之后,将功能分支合并到主线上,推送到共享\
版本库,完成开发。当然如果该特性分支不再需要时需要作些清理工作。参见\
图21-3所示的工作流程图。

.. figure:: /images/git-model/central-model-workflow-2.png
:scale: 80

图21-3:集中式协同模型工作流2


Gerrit 特殊的集中协同模型
Gerrit特殊的集中协同模型
---------------------------

**传统集中式协同模型的缺点**

传统集中式协同模型的主要问题是在管理上:谁能够向版本库推送?可以信赖某人向版本库推送么?
传统集中式协同模型的主要问题是在管理上:谁能够向版本库推送?可以信赖某人\
向版本库推送么?

对于在一个相对固定的团队内部使用集中式协同模型没有问题,因为大家彼此信赖,都熟悉项目相关领域。但是对于公开的项目(开源项目)来说,采用集中式的协同模型,必然只能有部分核心人员具有“写”权限,很多有能力的参与者被拒之门外,这不利于项目的发展。因此集中式协同模型主要应用在公司范围内和商业软件开发中,而不会成为开源项目的首选。
对于在一个相对固定的团队内部使用集中式协同模型没有问题,因为大家彼此信赖,\
都熟悉项目相关领域。但是对于公开的项目(开源项目)来说,采用集中式的协同\
模型,必然只能有部分核心人员具有“写”权限,很多有能力的参与者被拒之门外,\
这不利于项目的发展。因此集中式协同模型主要应用在公司范围内和商业软件开发\
中,而不会成为开源项目的首选。

**强制代码审核的集中式协同模型**

Android 项目采用了独树一帜的集中式管理模型 —— 通过 Gerrit 架设的审核服务器对提交进行强制审核。Android 是由大约近 200 个 Git 版本库组成的庞大的项目,为了对庞大的版本库进行管理,Android 项目开发了两个工具 repo 和 Gerrit 进行版本库的管理。其中 Gerrit 服务器为 Android 项目引入了特别的集中式协同模型。

Gerrit 服务器通过 SSH 协议管理 Git 版本库,并实现了一个 Web 界面的评审工作流。任何注册用户都可以参与到项目中来,都可以推送 Git 提交到 Gerrit 管理下的 Git 版本库(通过 Gerrit 启动的特殊 SSH 端口)。 Git 推送不能直接推送到分支,而是推送到特殊的引用 `refs/for/<branch-name>` ,此提交会自动转换为形如 `refs/changes/<nn>/<review-id>/<patch-set>` 的补丁集,此补丁集在 Gerrit 的 Web 界面中显示为对应的评审任务。评审任务进入审核流程,当通过相关负责人的审核后,才被接受,被合并到正式的版本库中。

在本书的第5篇第32章“Gerrit 代码审核服务器”中会详细介绍 Gerrit 代码审核服务器的部署和使用。
Android项目采用了独树一帜的集中式管理模型——通过Gerrit架设的审核服务器对\
提交进行强制审核。Android是由大约近200个Git版本库组成的庞大的项目,为了\
对庞大的版本库进行管理,Android项目开发了两个工具\ ``repo``\ 和\
``Gerrit``\ 进行版本库的管理。其中Gerrit服务器为Android项目引入了特别的\
集中式协同模型。

Gerrit服务器通过SSH协议管理Git版本库,并实现了一个Web界面的评审工作流。\
任何注册用户都可以参与到项目中来,都可以推送Git提交到Gerrit管理下的Git版\
本库(通过Gerrit启动的特殊SSH端口)。Git推送不能直接推送到分支,而是推送\
到特殊的引用\ ``refs/for/<branch-name>``\ ,此提交会自动转换为形如\
``refs/changes/<nn>/<review-id>/<patch-set>``\ 的补丁集,此补丁集在Gerrit\
的Web界面中显示为对应的评审任务。评审任务进入审核流程,当通过相关负责人的\
审核后,才被接受,被合并到正式的版本库中。

在本书的第5篇第32章“Gerrit代码审核服务器”中会详细介绍Gerrit代码审核服务\
器的部署和使用。

Loading

0 comments on commit 397c430

Please sign in to comment.