我只是无法理解这一点。我在网上和书籍上阅读了很多内容,但有些东西并没有留在我的脑海中。有人可以给我以下的虚拟版本:
- git fetch vs 拉取
- git 合并与变基
fetch
将从远程* 分支下载任何更改,更新您的存储库数据,但保持本地* 分支不变。
pull
将对您的本地分支执行fetch
和另外merge
的更改。
有什么不同? pull
使用拉取分支的更改更新您的本地分支。Afetch
不会推进您当地的分支机构。
鉴于以下历史:
C---D---E 本地 / A---B---F---G 遥控器
merge
将两个发展历史结合在一起。它通过在远程分支上分歧后重放本地分支上发生的更改来做到这一点,并将结果记录在新的提交中。此操作保留每个提交的祖先。
a 的效果merge
是:
C---D---E 本地 / \ A---B---F---G---H 遥控
rebase
将接受本地分支中存在的提交并将它们重新应用到远程分支之上。此操作会重写本地提交的祖先。
a 的效果rebase
是:
C'--D'--E' 局部 / A---B---F---G 遥控器
有什么不同?Amerge
不会改变提交的祖先。Arebase
重写本地提交的祖先。
*
此解释假定当前分支是本地分支,并且指定为 、 、 或 的参数的分支fetch
是pull
远程merge
分支rebase
。这是通常的情况。pull
,例如,将从指定分支下载任何更改,更新您的存储库并将merge
更改更新到当前分支。
获取与拉取
Git fetch 只是更新你的 repo 数据,但是 git pull 基本上会执行 fetch 然后合并提取的分支
合并与变基
来自 Atlassian SourceTree 博客,合并或变基:
合并将两条开发线结合在一起,同时保留每个提交历史的祖先。
相比之下,变基通过重写源分支的更改来统一开发线,使它们显示为目标分支的子级 - 有效地假装这些提交一直写在目标分支的顶部。
另外,请查看Learn Git Branching,这是一款刚刚发布到 HackerNews(帖子链接)的不错的游戏,它教授了很多分支和合并技巧。我相信这对这件事会有很大帮助。
拉取 vs 获取:
我理解这一点的方式是,这git pull
只是 agit fetch
后跟git merge
. 即,您从远程分支获取更改,然后将其合并到当前分支中。
合并与变基:
合并将按照命令执行;合并当前分支和指定分支之间的差异(合并到当前分支中)。即命令git merge another_branch
将合并another_branch
到当前分支。
变基的工作方式有点不同,而且很酷。假设您执行命令git rebase another_branch
。Git 会首先在当前分支和another_branch
. 即分支分歧之前的点。然后 git 会将这个分歧点移动到another_branch
. 最后,从新的分歧点重播自原始分歧点以来当前分支中的所有提交。这创建了一个非常干净的历史记录,分支和合并更少。
然而,它并非没有陷阱!由于版本历史被“重写”,因此只有在提交仅存在于本地 git 存储库中时,才应执行此操作。也就是说:如果您已将提交推送到远程仓库,则永远不要这样做。
这本在线书籍中关于变基的解释非常好,带有易于理解的插图。
使用变基而不是合并拉动
我实际上经常使用 rebase,但通常它与 pull 结合使用:
git pull --rebase
将获取远程更改,然后变基而不是合并。即它将重播您上次执行拉取时的所有本地提交。我发现这比使用合并进行正常拉取要干净得多,这将通过合并创建额外的提交。
合并- HEAD 分支将生成一个新的提交,保留每个提交历史的祖先。如果合并提交是由多个在同一分支上并行工作的人进行的,那么历史可能会被污染。
Rebase - 将一个分支的更改重新写入另一个分支,而不创建新的提交。代码历史是简化的、线性的和可读的,但它不适用于拉取请求,因为你看不到有人做了什么细微的改变。
git merge
在处理基于功能的工作流或我不熟悉 rebase 时,我会使用它。但是,如果我想要一个更干净、线性的历史,那么git rebase
更合适。有关更多详细信息,请务必查看此合并或变基文章。