`git merge`和`git merge –no-ff`有什么区别?

使用gitk log ,我不能发现两者之间的差异。 我怎样才能观察到不同(使用git命令或一些工具)?

如果检测到你的当前HEAD是你要合并的提交的祖先,那么--no-ff标志可以防止git merge执行“快进”。 快进是,而不是构build一个合并提交,git只是移动你的分支指针指向传入的提交。 这通常发生在没有任何本地更改的情况下执行git pull

然而,有时候你想防止这种行为发生,通常是因为你想维护一个特定的分支拓扑结构(例如,你正在合并一个主题分支,并且你希望在阅读历史时确保它看起来像这样)。 为了做到这一点,你可以传递--no-ff标志,而git merge始终构造一个合并而不是快进。

同样的,如果你想执行一个git pull或者使用git merge来显式快速转发,并且你希望如果不能快速转发,那么你可以使用--ff-only标志。 通过这种方式,你可以经常做一些像git pull --ff-only东西,而不用考虑,然后如果出错了,你可以回去决定是否要合并或重新绑定。

graphics回答这个问题

这里有一个使用git merge --no-ff的清晰解释和graphics化插图:

git merge --no-ff和git merge的区别

直到我看到这个,我完全失去了git。 使用--no-ff可以让查看历史logging的人清楚地看到您检查出来的分支 。 (该链接指向github的“networking”可视化工具)这里是另一个插图很好的参考 。 这个参考对第一个很好的补充了,更多地关注了那些不熟悉git的人。


像我这样的新人的基本信息

如果你和我一样,而不是一个Git-guru, 我的答案在这里描述处理从git的跟踪删除文件,而不从本地文件系统中删除,这似乎很lesslogging,但经常发生。 另一个新的情况是获得当前的代码 ,仍然设法避开我。


示例工作stream程

我更新了一个包到我的网站,不得不回到我的笔记看到我的工作stream程; 我认为这是一个有用的例子添加到这个答案。

我的git命令工作stream程:

 git checkout -b contact-form (do your work on "contact-form") git status git commit -am "updated form in contact module" git checkout master git merge --no-ff contact-form git branch -d contact-form git push origin master 

如下:实际使用情况,包括说明。
注意:下面的输出是剪切的; git是相当详细的。

 $ git status # On branch master # Changed but not updated: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: ecc/Desktop.php # modified: ecc/Mobile.php # deleted: ecc/ecc-config.php # modified: ecc/readme.txt # modified: ecc/test.php # deleted: passthru-adapter.igs # deleted: shop/mickey/index.php # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # ecc/upgrade.php # ecc/webgility-config.php # ecc/webgility-config.php.bak # ecc/webgility-magento.php 

注意以上三点:
1)在输出中,您可以看到ECC软件包升级的更改,包括添加新文件。
2)还要注意,有两个文件(不在/ecc文件夹中),我独立于此更改而被删除。 不要将这些文件删除与ecc混淆,我将在稍后创build一个不同的cleanup分支来反映这些文件的删除。
3)我没有按照我的工作stream程! 当我试图让ecc再次工作时,我忘了git。

下面:而不是做全包的git commit -am "updated ecc package"我通常会,我只想在/ecc文件夹中添加文件。 这些被删除的文件并不是我的git add一部分,但是因为他们已经在git中被跟踪了,所以我需要从这个分支的提交中删除它们:

 $ git checkout -b ecc $ git add ecc/* $ git reset HEAD passthru-adapter.igs $ git reset HEAD shop/mickey/index.php Unstaged changes after reset: M passthru-adapter.igs M shop/mickey/index.php $ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks" $ git checkout master D passthru-adapter.igs D shop/mickey/index.php Switched to branch 'master' $ git merge --no-ff ecc $ git branch -d ecc Deleted branch ecc (was 98269a2). $ git push origin master Counting objects: 22, done. Delta compression using up to 4 threads. Compressing objects: 100% (14/14), done. Writing objects: 100% (14/14), 59.00 KiB, done. Total 14 (delta 10), reused 0 (delta 0) To git@github.com:me/mywebsite.git 8a0d9ec..333eff5 master -> master 


上面的自动化脚本

在一天中使用这个过程10次以上,我已经写了批处理脚本来执行命令,所以我做了一个几乎正确的git_update.sh <branch> <"commit message">脚本来完成上述步骤。 这是剧本的主要来源 。

而不是git commit -am我从通过git status生成的“modified”列表中select文件,然后粘贴到这个脚本中。 这是因为我做了几十个编辑,但想要不同的分支名称来帮助分组变化。

--no-ff选项确保不会发生快进合并,并且总是会创build一个新的提交对象 。 如果你想让git维护一个function分支的历史,这可能是可取的。 git merge --no-ff vs git merge 在上图中,左边是使用git merge --no-ff之后的git历史logging的例子,右边是使用git merge进行ff合并的例子。

编辑 :此图像的以前版本指示合并提交只有一个父代。 合并提交有多个父提交 git用来维护“function分支”的历史和原始分支。 多个父链接以绿色突出显示。

这是一个古老的问题,这在其他文章中有些微妙的提及,但是对于我来说这个点击的解释是非快进合并将需要单独的提交

Interesting Posts