Understanding Git Conceptually 从概念上理解Git【2】

原文:http://www.eecs.harvard.edu/~cduan/technical/git/git-2.shtml

翻译:http://blog.csdn.net/yhcharles/article/details/6596816

Branching(分支)的目的

假设你正在做一篇论文。你完成了第一份草稿,并且提交评审了。然后你得到了一些新的数据,于是你着手把这些新的内容加到论文中。当你正做到一半的时候,评审委员会给你打电话,告诉你其中有些章节的标题需要进行修改,以符合格式要求。这时你会怎么做?

显然你不想把你正修改到一半的论文换上正确的标题发出去。你希望做的,是回到你当初发送出去的版本,修改好标题,然后再重新发送,同时把最近的工作安全的保存在另外某个地方。

这就是branching背后的思想,Git让这件事情变得简单。

注意术语:术语“branch”和“head”在Git中几乎是同义词。每个branch都有一个head来代表,并且每一个head代表一个branch。有时候,“branch”被用来表示一个head以及该head的所有历史commit,而“head”只表示一个commit对象,即该branch中的最近一个commit。

创建一个branch

假设你的repository是这样的:

(A) -- (B) -- (C)
               |
             master
               |
              HEAD

这里(B)是你发送给委员会的版本,(C)是你现在工作的版本。(这里没有画箭头,可以想象它们总是指向左边的)

为了跳回到commit (B)进行修改,首先你需要知道如何引用该commit。你可以用git log来查到(B)的SHA1名字,或者用HEAD^来表示。

现在,我们可以用git branch命令了:

git branch [new-head-name] [reference-to-(B)]

或者,例如:

git branch fix-headers HEAD^

这个命令会用给出的名字创建一个新的head,并且将其指向指定的commit对象。如果没有指定commit对象,那么它会指向 HEAD

现在,我们的commit树看起来是这样的:

(A) -- (B) ------- (C)
        |           |
   fix-headers    master
                    |
                   HEAD

在branch之间切换

为了开始在这些head上开始工作,你需要把fix-headers设置成当前的head。可以用git checkout来做:

git checkout [head-name]

该命令做了这些事情:

  • HEAD指向[head-name]表示的commit对象
  • 将当前目录中的所有文件替换成新HEAD commit中的文件版本
重要提示:如果你在运行 git checkout时还有未提交的修改,那么Git的行为会变得很诡异。虽然这些诡异的行为是可预见的,甚至有时候也是有帮助的,但是最好还是避免出现。当然,你需要做的仅仅是在check out新head之前提交你所有的修改。

在check out fix-headers之后,你就可以修改标题了。然后你添加并提交这些修改。得到的repository看起来是这样:

         +-------------- (D)
        /                 |
(A) -- (B) -- (C)         |
               |          |
             master  fix-headers
                          |
                         HEAD

(现在你可以看到为什么称为“branching”了:commit树新生长出了一个分支。注意(B)和(C)之间的夹角可以忽略;指针箭头不会关心它们是水平的还是斜的)

master的祖先是(C),(B),(A)。fix-headers的祖先是(D),(B),(A)。你可以用git log查看到。

相关的命令:

这里还有其它一些有用的命令:

  • git brach不带参数,用来列出目前所有的head,在当前head旁用星号标出
  • git diff [head1]..[head2]列出head2head1指向的commit之间的diff
  • git diff [head1]...[head2](注意是三个点)列出head2head1head2的共同祖先之间的diff。例如,在上面的例子中diff master...fix-headers会列出(D)和(B)的diff
  • git log [head1]..[head2]列出head2head1head2共同祖先之间的修改日志。如果是三个点,那么会列出head1和共同祖先之间的修改日志;这个用处不大。(切换head1head2相对来说更有用)
常用的branch模式

一种使用Git branch常用的方式是,保留一个“main”或者“trunk”分支,创建其他新的分支用来实现新的特性。通常,缺省的Git分支,master,被用来作为main分支。

因此,在上面的例子中,把master留在(B)可能更好,这个分支用来提交给评审。然后,你可以开一个新的分支用来保存为新数据做的修改。

理想情况下,用这种模式,master分支始终是可发布的状态。其它分支会包含完成到一半的工作,新的特性等等。

当有多有开发者为同一个项目工作时,这种模式尤其重要。如果所有开发者都在向同一个分支添加commit,那么新特性必须在单个commit完成添加,以免使得这个branch变成不可用状态。但是,如果每个开发者创建一个新的branch来开发新的特性,那么就可以随时进行commit,不管是否已经完成。

这就是Git用户说commit很廉价的意思。如果你工作在你自己的branch上,那你就没有必要在提交commit时慎之又慎。反正它不会对其它事情有任何影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值