评论
-
还好我往master merge的时候都要先更新。。
我刚才试了试gitg,挺cute的,可是仔细一对比发现不清晰,我repo里这么简单的一个操作就有绕麻花的迹象了
我很好奇你的repo用qgit打出来会不会clean一点儿,能不能发上来看看。。 -
今天又有些概念不清来读了遍。不过好像有两个地方需要小改动一些:
merge <branch> of <source_url> to <branch> 我想应该是 merge <branch> of <source_url> into <branch>
你在ruby-china的讨论:http://ruby-china.org/topics/112 里面二楼回复也是这样写的。
git check master 我想应该是 git checkout master
-
=============『2. 避免线索“扭麻花”』
=============2) 但是向线上的 master push 的时候发生了冲突,因为线上的 master 比自己本地的 master 新。这个图是表示origin/master和local/master合并过了的??
=============如果你事先把 master 更新,线索就会是这样的:
这个图为什么feature A会有第三个commit?不是merge commit在master线上么??
最后一个问题,在合并分支的时候,
1. 首先在local/master pull最新的(与origin/master同步)
2. 然后merge --no-f OneBranch
3. 最后 push origin master要是在push之前,又有人更新了origin/master,此时我在local/master上push会被reject,这个时候是用git pull --rebase去解决conflict么??
感觉rebase虽然让分支清晰,使用起来考虑的东西确实太多谢谢!
-
@final0pro 我这篇文章对身边人的推广效果是失败的,一开始用 rebase 就会把 push 搞得一团糟,后来我就开始推广不要 rebase 了,除非清楚自己在做什么。
推荐看 Pro Git http://git-scm.com/book/zh ,比我说的清晰多了。
-
自己又实践了下,还是同样的问题
在合并分支的时候,
1. 在local/master,pull最新的(与origin/master同步)
2. 在local/master,执行merge --no-f OneBranch
3. fix some conflicts(这个时候有人push新的东西到了origin/master)
4. push origin master所以就是
1. [master] git pull
2. [master] git merge --no-ff one_branch
3. // fix conficts(at this time, one guy push new stuffs to origin/master)
4. [master] git push
5. //rejected
6. [master] git pull
8. [master] git push这样git竟然会生产一个新的commit,感觉很奇怪,branch感觉不易读
-
楼主是否知道最开始的那张流程图是用何软件来绘制的?看着很舒适
原文转载自: http://codecampo.com/topics/379?comment_id=1354#comment-1354
用 Git 也有一段时间了,看过一些 Git 工作流的文章,加上工作和业余中参与一些项目开发,对 Git 的工作流有一些心得,写下来整理一下。
如果你对 Git 并不是很熟悉,推荐两份阅读资料:
本篇文章是基于中心式的代码管理,但如果你理解其内涵,会发现这跟一般的 github 托管的开源项目是兼容的,只要把每个 fork 都当成特性分支,而项目的发源地是中心。
0. 理想的历史线索
首先看一下这个流传很广的图(取自 A successful Git branching model)
这确实是一个理想的版本分支控制流程,至少它有以下优点:
但是,实际中如果不加注意,很容易变成这样:
这个历史线索有两个很糟糕的地方:
实际上这种情况的发生很普遍,如果你自己在维护一个项目,并且有多人参与开发,可以用 gitg 这个工具打开项目目录看一看。
下面将会分析图中问题产生的原因和解决方法。
1. 不要产生多余的分支
留意到上一节的糟糕例子中,有几条 merge 信息是这样的格式:
这类 merge 是在开发者向 git 源 push 的时候发生冲突,然后运行
git pull
的时候产生的。git pull
确实很便利,但是却产生了副作用:一个特性分支变成了两个。如果你认为每个 git 源都是平等的,而且每个开发者都是平等的,这没什么问题。不过如果需要一个中心式的开发历史,这些本地分支的合并信息就会成为干扰。
解决这些多余的 merge 信息的解决方案就是—— rebase。
pull --rebase
可以基于远程分支重写自己的本地 commit,从而产生干净的线索。有人可能会提出异议,
pull --rebase
丢失了并行开发的这一信息,没错,这取决于你的项目开发是怎样的管理。如果你跟我一样喜好干净的分支线索,那么同一分支的提交应该用pull --rebase
。确实需要保留分支线索的,应该另外开一条分支,而不要pull
。注意,
rebase
某些时候是个危险的工具,因为它实际改写了你的 commit,千万不要rebase
一些已经提交到公共源的 commit,详情可以看 progit 中 分支的衍合 这一章节。2. 避免线索“扭麻花”
依然是这个图
除了多出的分支外,还有一个严重的问题,就是主干线索(internal)被痛苦的扭到了一边。如果这种情况反复出现,各个线索就会像麻花一样扭在一起。
现在来重现一下这种扭麻花出现的原因:
1) 开发者以本地的 master 为基础新建了一个分支 feature A,以此工作,中途更新过 master,然后在工作完成后 merge 回 master 分支。
2) 但是向线上的 master push 的时候发生了冲突,因为线上的 master 比自己本地的 master 新。
3) 然后,开发者执行了
git pull
4) 最后,开发者愉快的
git push
,线上的 master 分支将会和本地一样这样会导致什么问题呢?问题就是如果某个 commit 有 bug,你将无法查证这个 commit 被归入主干分支的上线时间。例如上图的红色色块,看起来是在最新的 merge 之后才进入 master 的,但是它在之前已经进入 master 了。作为 master 分支(甚至任一分支)的管理者,肯定不希望分支的主线索一直在开发者的本地线索中来回切换。
解决方法是,一定要在 merge 之前,将主干分支更新到最新状态。
如果你事先把 master 更新,线索就会是这样的:
bug 点在什么时候进入主干分支一目了然。
3. 线上分支合并一定要用 merge --no-ff
假设你已经知道,git 中的合并默认是快进合并(fast-forward)
线上分支间的快进合并会产生一个问题,就是丢失了合并的时间戳。试问上图的红色有 bug commit 是什么时候进入主分支?
如果每次分支合并时加上 --no-ff 参数,就可以避免信息的丢失
bug 进入主干的时间将很清晰。
4. 总结
假如上面的规则让你感到混乱,那么下面整理两个法则,分别适用于两种身份。
1) 代码提交者身份
向远程分支提交代码时,先
git pull --rebase
,避免把本地状态当作分支提交。2) 分支管理者身份
进行线上分支合并时,一律使用
git merge --no-ff
,保留合并时间戳。不要混用两种身份,一边进行代码提交,一边进行分支合并。这样你的 git 管理将会轻松很多。