git -- Fast forward(快进模式)和 no-ff 区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了git -- Fast forward(快进模式)和 no-ff 区别相关的知识,希望对你有一定的参考价值。
参考技术A表示 快进模式 合并,即 直接将当前分支指针指向要合并的分支
gitk --all 查看
gitk --all 查看
说明:此时 dev1.0是master的上游。4个commit是线性的。此时切换到master合并dev1.0,master分支会进行快速合并模式(fast-forward),直接将master的HEAD指向dev1.0的HEAD;
使用fast forward的缺点:
如果禁用掉 Fast-forward (快进模式),就可以生成新的commit,从而避免了“一旦dev1.0删除或者新提交commit,master的第三、四个commit很难知道是通过合并dev1.0的”:
所以,使用no-ff进行merge。当dev1.0进行新提交commit,我们依旧可以知道master有跟dev1.0进行merge产生了一个commit;
详细见下面:
删除dev1.0依旧能看到master的commit(黄色HEAD)是通过merge得到的。
Todogit的fast forward & git命令学习
git的fast-forward在之前的文章有介绍过,但是介绍的不细:
http://www.cnblogs.com/charlesblc/p/5953066.html
fast-forward方式就是当条件允许的时候,git直接把HEAD指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。
因为在这个过程中没有创建commit squash 是用来把一些不必要commit进行压缩,比如说,你的feature在开发的时候写的commit很乱,那么我们合并的时候不希望把这些历史commit带过来,
于是使用--squash进行合并,此时文件已经同合并后一样了,但不移动HEAD,不提交。需要进行一次额外的commit来“总结”一下,然后完成最终的合并。 --no-ff指的是强行关闭fast-forward方式。
有这篇文章详细复习一下 (Link)
通常,合并分支时,如果可能,Git会用Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
实战一下--no-ff
方式的git merge
:
首先,仍然创建并切换dev
分支:
$ git checkout -b dev Switched to a new branch \'dev\'
修改readme.txt文件,并提交一个新的commit:
$ git add readme.txt $ git commit -m "add merge" [dev 6224937] add merge 1 file changed, 1 insertion(+)
现在,我们切换回master
:
$ git checkout master
Switched to branch \'master\'
准备合并dev
分支,请注意--no-ff
参数,表示禁用Fast forward
:
$ git merge --no-ff -m "merge with no-ff" dev Merge made by the \'recursive\' strategy. readme.txt | 1 + 1 file changed, 1 insertion(+)
因为本次合并要创建一个新的commit,所以加上-m
参数,把commit描述写进去。
合并后,我们用git log
看看分支历史:
$ git log --graph --pretty=oneline --abbrev-commit * 7825a50 merge with no-ff |\\ | * 6224937 add merge |/ * 59bc1cb conflict fixed ...
可以看到,不使用Fast forward
模式,merge后就像这样:
关于默认的fast-forward的,上面引文没有详述。基本就是看不出有从其他分支合并过来的信息,只能看到每个commit实际的信息。如果其他分支丢失了,分支合并的信息就丢失了。
我自己试了一下 默认的有fast-forward的情况。如下:
$ git checkout -b testff Switched to a new branch \'testff\' $ vi readme $ git add readme $ git commit readme test ff # Please enter the commit message for your changes. Lines starting # with \'#\' will be ignored, and an empty message aborts the commit. # Explicit paths specified without -i or -o; assuming --only paths... # On branch testff # Changes to be committed: # new file: readme #
... ".git/COMMIT_EDITMSG" [converted] 8L, 282C written [testff 5a036ee] test ff 1 file changed, 1 insertion(+) create mode 100644 readme $ git checkout -b newtestff Switched to a new branch \'newtestff\' $ git merge testff Already up-to-date. $ git diff testff newtestff $ git checkout master Switched to branch \'master\' Your branch is up-to-date with \'origin/master\'. $ git pull $ git checkout -b newff Switched to a new branch \'newff\' $ git checkout newff Already on \'newff\' $ git merge testff Updating 30a974d..5a036ee Fast-forward readme | 1 + 1 file changed, 1 insertion(+) create mode 100644 readme $ git log --graph --pretty=oneline --abbrev-commit * 5a036ee test ff * 30a974d Merge branch \'xxx\' into master |\\ ...
重点看两点:
1. 第一处飘黄的地方,是在test-ff版本 checkout -b的,结果发现git 两个branch完全没有差别。
git checkout -b dev命令相当于
创建分支: git branch dev 切换分支: git checkout dev
而这个创建是基于当前HEAD的。
所以新创建的分支和test-ff没有区别。
2. 采用默认的merge之后,使用git log --graph --pretty=oneline --abbrev-commit 能够看到:
* 5a036ee test ff
完全没有原来 test-ff 分支的信息。
另,git log命令加上后面的参数很好用,--graph --pretty=oneline --abbrev-commit
比原始的输出好看多了。
分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本;
你和你的小伙伴们每个人都在dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。
所以,团队合作的分支看起来就像这样:
小结
Git分支十分强大,在团队开发中应该充分应用。
合并分支时,加上--no-ff
参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward
合并就看不出来曾经做过合并。
一些git命令:
git checkout -b dev//基于本地创建分支 git checkout -b dev origin/dev //基于远程分支创建本地分支 可以看到git checkout -b命令相当于 创建分支: git branch dev切换分支: git checkout dev 是基于当前HEAD的 删除本地分支 git branch -D dev 删除远程分支 git push origin :branch-name 冒号后面没有空格
下面再对这些内容做一下复习:
http://www.ruanyifeng.com/blog/2015/12/git-workflow.html
http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
http://www.ruanyifeng.com/blog/2015/08/git-use-process.html
http://www.ruanyifeng.com/blog/2014/06/git_remote.html
以上是关于git -- Fast forward(快进模式)和 no-ff 区别的主要内容,如果未能解决你的问题,请参考以下文章