如何理解git的分布式 分支
看了Git官网的这一段介绍更加迷惑了
用 Git 的话,就算你在飞机或者火车上,都可以非常愉快地频繁提交更新, 等到了有网络的时候再上传到远程仓库。同样,在回家的路上,不用连接VPN 你也可以继续工作。换作其他版本控制系统,这么做几乎不可能,抑或非常麻烦。
链接地址》》》
假如
有一个商城项目正在上线,团队中有A、B、C三个程序员,使用git来进行版本控制。总共开发天数是10天,从第1天到第5天,A、B、C都是一起开发,一起提交,一个版本。但是到了第6天开始,C就不提交到远程了,一直都是在自己修改制作。整个项目很多文件,C会把项目中的文件GlobalFunction.php改动很多次,修改了很多函数,也加入了很多自己的函数。随着开发的继续,C还会不断的陆续修改GlobalFunction.php文件。而一直都提交到远程的A和B,也需要经常修改GlobalFunction.php文件,但是A和B会保持同步到Git远程。
合并
到了最后第10天,C可以联网了,然后C提交到远程。可C电脑里面的GlobalFunction.php 跟 Git远程上的 GlobalFunction.php 已经完全不一样了,而且远程的这个文件还经历过了二十多个版本。而C自己电脑里面的也经历过了几十个不同版本。
极大的疑惑
根据git介绍中的那一段的描述,这样的情况下,Git是可以自动合并?如何自动合并?
C已经在GlobalFunction.php中加入了很多函数且期间也经历过了很多次的版本。
补充
看到很多介绍Git的文章重点都放在了不需要push到远程,不需要联网就可以使用,真的觉得实在是难以理解。我在sf问也有很多人也在说不用push, http://segmentfault.com/q/1010000000605934#c-1020000000606050-1050000000609657 ,更让人迷惑。不用push,假如1年或者10年了从来都不push到远程,那么还算是协同工作了吗,git会那么神奇10年之后再联网push过去还可以自动合并
Answers
终于遇到一个可以好好回答的问题了;
首先说一下题主的假设:
C 从第 6 天开始不跟远程交互了,自己玩了,这是做什么?这不是分布式,分布式是在网络可用下说的,分布式不是隔着几天不跟远程同步;
既然文件叫
GlobalFunction.php
,那么这个文件就是修改极少的(或者说修改相同的一行是很少的),类似于
Python
下的
setup.py
,有时只是到了新版本发布的时候你才会修改一下
version
变量吧;
GIT 的分支概念个人理解是可以更快速的基于某个或某些分支进行协作开发,比如一个仓库
foo
有一个 分支叫做:
master
,那么 A,B,C 进行协同开发的时候会在本地基于这个共同的分支
master
进行本地分支,比如 A 的本地分支叫
a-dev
,B 的叫:
b-dev
,C 的叫
c-dev
,怎么来的呢?
git checkout -b xxx origin/master # xxx 代表 `a-dev` 等
其次说一下题主说的合并:
如果 C 在本地基于
master
进行了本地分支
c-dev
那么 C 一直可以更新本地 master 分支而不影响本地分支
c-dev
(而此时你可以一直在
c-dev
分支):
git pull origin master:master
那么把本地
master
更新了,怎么反应在
c-dev
呢? 很简单,GIT 已经为你想好了:
git rebase master # 此时你在 `c-dev` 分支
经过了上面,可能会发生的情况无非是两种:1. 出现合并冲突,
rebase
失败;2. 无冲突(可能会自动
merge
),本地
master
最新状况跟本地
c-dev
合并;
对于 1 的出现,GIT 不会自动搞定冲突,却可以尝试自动合并(
merge
),失败了,叫出现了冲突;出现了冲突一般是指不同的提交,修改了同一文件的同一行(几行)内容,需要开发者自己搞定冲突;
个人总结
分支是 GIT 区别于其他集中式版本控制系统的杀手锏(
killer feature
);rebase
是 GIT 分支的杀手锏;GIT 的分布式特性离不开 GIT 良好的分支特性;