我实在是不理解这个问题。我已经在网上和书本上读了很多,但仍然有些东西没有留在我的脑海中。可以有人给我以下操作的简单版本吗?:
- git fetch 与 pull 的区别
- git merge 与 rebase 的区别
我实在是不理解这个问题。我已经在网上和书本上读了很多,但仍然有些东西没有留在我的脑海中。可以有人给我以下操作的简单版本吗?:
fetch
将下载远程*分支的任何更改,更新您的存储库数据,但不会更改您的本地*分支。
pull
将执行fetch
并将更改合并到您的本地分支中。
有什么区别?pull
使用来自提取的分支的更改更新本地分支。 fetch
不会推进您的本地分支。
给定以下历史记录:
C---D---E 本地 / A---B---F---G 远程
merge
将两个开发历史记录连接在一起。 它通过在远程分支之上重放发生在本地分支分叉后的更改,并在新提交中记录结果来完成此操作。 此操作保留每个提交的祖先关系。
一个merge
的效果将是:
C---D---E 本地 / \ A---B---F---G---H 远程
rebase
将接受存在于您的本地分支中的提交,并将它们重新应用在远程分支之上。 此操作将重写您本地提交的祖先关系。
一个rebase
的效果将是:
C'--D'--E' local / A---B---F---G remote
有什么区别?merge
不会更改提交的祖先关系。 rebase
重写了您本地提交的祖先关系。
*
此解释假设当前分支是本地分支,并且作为fetch
、pull
、merge
或rebase
参数指定的分支是远程分支。这是通常的情况。pull
,例如,将下载任何来自指定分支的更改,更新存储库并将更改合并到当前分支中。
抓取(Fetch)与拉取(Pull)
Git 抓取只是更新您的仓库数据,但 git 拉取将执行抓取然后合并拉取的分支。
合并(Merge)与变基(Rebase)
来自 Atlassian SourceTree Blog 的 Merge or Rebase:
合并将两个开发分支合并在一起,同时保留每个提交历史记录的祖先关系。
相比之下,变基通过重新编写源分支的更改,使它们出现在目标分支的子级位置,从而统一了开发分支 - 事实上,它假装这些提交一直都是在目标分支上编写的。
还可以查看Learn Git Branching,这是一个很好的游戏,刚刚发布到 HackerNews (帖子链接),可以教授很多分支和合并技巧。 我相信这对这个问题非常有帮助。
git merge <remote>/<branch>
。例如,如果您在主分支上,并且您的远程名称为origin,则可以执行git merge origin/master
。 - Felipe Sabinopull vs fetch:
据我理解,git pull
简单来说就是 git fetch
加上 git merge
。也就是说,你从远程分支获取变更,然后将其合并到当前分支。
merge vs rebase:
使用合并命令会将当前分支与指定分支之间的差异进行合并(到当前分支)。比如说,git merge another_branch
命令会将 another_branch
合并到当前分支。
而使用变基命令则有所不同,它非常强大。假设你执行了命令 git rebase another_branch
,Git 首先会找到当前分支和 another_branch
的最新公共版本,即这两条分支在分叉前的那个点。然后 Git 会将这个分叉点移动到 another_branch
的最新提交处。最后,所有自分叉点以来当前分支中的提交都被“重演”到新的分叉点上。这样就创建了一个非常干净的历史记录,减少了分支和合并操作。
但是,这样做也有风险!因为版本历史被“重写”了,所以只有当提交只存在于你的本地 Git 仓库中时,才应该这样做。也就是说:如果你已经将提交推送到远程仓库,那么千万不要操作。
在这本在线书籍中,有一份非常好的关于变基的解释和易于理解的插图。
pull with rebasing instead of merge
实际上,我经常使用变基命令,但通常与 pull 命令结合使用:
git pull --rebase
将获取远程更改,然后重新定位到基底位置而不是合并。即,它将重放所有你自上次执行拉取以来的本地提交。我认为这比使用常规合并进行普通拉取更加清晰,因为它会创建一个带有合并的额外提交。
合并 - HEAD分支将生成一个新的提交,保留每个提交历史的祖先。如果多个人在同一分支上并行工作,则历史记录可能会变得污染。
变基 - 将一个分支的更改重写到另一个分支上,而不创建新的提交。代码历史简化、线性和可读,但它不能与拉取请求一起使用,因为你看不到其他人所做的微小更改。
当处理基于特性的工作流程或者我不熟悉变基时,我会使用git merge
。但是,如果我想要一个更干净、线性的历史记录,那么git rebase
更加适合。有关更多详细信息,请务必查看this merge or rebase article。