正如您在问题中所暗示的那样,其中最令人困惑的部分是了解与远程存储库相比对本地存储库的影响,以及对使用远程存储库的其他所有人的影响。
首先,正如其他答案所示,git pull 与git fetch + git merge 字面上相同。这两个命令都是从本地仓库拉取/获取 + 合并从远程到本地仓库的角度来看的。这发生在您在远程本地签出到本地该分支的同一个分支上。我会先讨论这些,然后再讨论压缩和变基。
Git 拉取 / Git Fetch + Git 合并
假设您已在本地签出master,然后您将从远程获取master(除非您在这些命令上使用一些更高级的语法或标记)。我们将远程分支称为origin/master。
从origin/master 获取意味着您希望从origin/master 获取新提交并更新origin/master 的本地跟踪参考以匹配master 实际在远程的位置。如果master 在本地和远程之间存在分歧,那么将会有提交从您的主分支分支出来,直到它们到达origin/master 引用的当前位置。您最近未推送的提交将位于可能不同的本地 master 分支上。
然后,当合并发生时,您基本上要求将 origin/master 合并到您本地的 master 分支中。如果您执行正常的合并命令,这将导致对本地 master 分支的新提交将所有最近的更改从 origin/master 拉入本地 master 分支。如果有冲突,您将在提交之前先解决它们。但是,如果您没有在本地提交任何内容,则合并可以快速前进到新的 origin/master 位置,而无需执行任何其他操作(您的 master 将向前跳转以匹配 origin/master)。
此时,如果您在其他任何人向远程推送更多内容之前推送,那么您的新合并提交将与您的单独提交(它们看起来像一个单独的、未命名的分支)和原始远程提交一起推送,最后加上一个新的合并提交。
挤压呢?
您确实问过这个问题,但是如果您与 --squash 合并,那么它将添加合并提交,但删除其他本地提交,因此历史记录中没有额外的未命名分支。有些人更喜欢它,因为它“更干净”,而另一些人则更喜欢查看所有历史记录(即代码分歧以及合并提交中究竟汇集了什么)。
变基
当您变基时,您基本上是在获取所有本地提交,并将它们重播到远程主分支上,因此它们不会显示为单独的分支。这使本地历史保持完整,而没有显示代码分歧,同样,有些人更喜欢并认为它更“干净”。这与任何历史记录是否重要等无关。
如果其他人在我获取后提交了怎么办?
如果其他忍者在您获取后提交(嗯,只是提交......),那么您的推送将失败。你可以使用--force,但是你会完全覆盖他们的提交,所以这通常是不受欢迎的,因为它会给其他人带来各种各样的问题。在这种情况下,如果每个人都同意他的提交应该先进行,那么您将需要再次执行该过程(如果没有冲突,那么这将是快速而简单的),但总的来说,团队需要有一个策略在这类事情上,一旦团队足够大,通常会使用拉取请求和审查来以更有序的方式管理推送。
另一种思考方式
将本地主分支视为与远程分支分开的分支,可能很容易理解正在发生的事情 - 从 Git 的角度来看,这基本上是正在发生的事情。
事实上,在我看来,在你准备好将某些东西合并到远程分支之前,你总是最好在自己的单独分支中工作。 Git 让拥有一个单独的分支变得如此简单、快速和轻松,这就是我所做的。