为什么git pull提供了合并的机会,而git push没有';T
(我下面描述的都是在本地git回购中进行的实验,不涉及远程回购。) 我创建了两个本地分支为什么git pull提供了合并的机会,而git push没有';T,git,Git,(我下面描述的都是在本地git回购中进行的实验,不涉及远程回购。) 我创建了两个本地分支lb1和lb2。它们从同一个提交节点开始 git branch lb1 git branch lb2 我让它们在彼此的上游。详情如下: $ git checkout lb2 Switched to branch 'lb2' $ git branch -u lb1 Branch lb2 set up to track local branch lb1. $ git checkout lb1 Switche
lb1
和lb2
。它们从同一个提交节点开始
git branch lb1
git branch lb2
我让它们在彼此的上游。详情如下:
$ git checkout lb2
Switched to branch 'lb2'
$ git branch -u lb1
Branch lb2 set up to track local branch lb1.
$ git checkout lb1
Switched to branch 'lb1'
$ git branch -u lb2
Branch lb1 set up to track local branch lb2.
然后我通过对每一个进行不同的更改使它们分开。如下图所示:
我目前在lb1
。然后我试着将一个分支(lb1)推到另一个分支(lb2)上,看看会发生什么:
$ git push . lb1:lb2
To .
! [rejected] lb1 -> lb2 (non-fast-forward)
error: failed to push some refs to '.'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
因此,如果我理解正确,它会说推送的分支尖端(lb1
)在其远程对应物(lb2
)后面。我必须首先签出lb1
,然后从lb2
中提取以集成lb2
的更改
所以我这样做:(注意我现在在lb1
分支上)
所以,git pull
给了我一个合并的机会
合并后,我可以将lb1
推送到lb2
:
$ git push . lb1:lb2
Total 0 (delta 0), reused 0 (delta 0)
To .
cdd1247..2dfb555 lb1 -> lb2
修订图如下所示:
并且lb2
的更改被添加到lb1
的日志历史记录中:
总结如下:
- lb1—推-->lb2:失败
- lb1我认为@dunni在评论中一针见血(即将钉子合并到板中),他们提到了一个
实际上是两个不同操作的方便符号。我想从你问题的断言中挑战的是,git pull
与git pull
是对称的。更准确的说法是,git push
与git fetch
对称。当然,正如你所说,在英语中,推和拉实际上是对立的;然而,这并不一定意味着它们在其他领域的使用是对称的 至于为什么git的实现者决定让git push
尝试自动合并,我只能推测。我的理论是,因为工作回购有跟踪分支的概念,所以自动将远程跟踪分支合并到本地分支以执行拉操作是有意义的。这是因为您必须执行合并/快进操作,才能在非分离头部状态下使用更新。存储库必须保持这种分离,以便了解远程提交的内容与本地提交的内容。然而,远程的裸存储库没有跟踪分支的概念:它只是在后端运行pull
时更新其引用。它不关心引用了什么提交;这就是强制推送(git-receive-pack
)存在的原因。事实上,强制推送甚至不是git pack协议中的一个构造,而只是一个客户端选项,用于忽略保持历史完整性的常规检查。推送时,并不意味着需要合并/快进:只意味着更新远程对象数据库及其引用列表。在客户端,只需更新远程跟踪分支以匹配成功推送的内容(无论是否强制)gitpush-f
总而言之:获取需要合并,因为获取的远程跟踪分支必须合并到相应的本地分支中,以便在工作存储库中使用。然而,使用push,您可能不一定需要合并;您只是在更新远程分支。我认为@dunni在评论中一针见血(即将钉子合并到板中),他们提到了一个
实际上是两个不同操作的方便符号。我想从你问题的断言中挑战的是,git pull
与git pull
是对称的。更准确的说法是,git push
与git fetch
对称。当然,正如你所说,在英语中,推和拉实际上是对立的;然而,这并不一定意味着它们在其他领域的使用是对称的 至于为什么git的实现者决定让git push
尝试自动合并,我只能推测。我的理论是,因为工作回购有跟踪分支的概念,所以自动将远程跟踪分支合并到本地分支以执行拉操作是有意义的。这是因为您必须执行合并/快进操作,才能在非分离头部状态下使用更新。存储库必须保持这种分离,以便了解远程提交的内容与本地提交的内容。然而,远程的裸存储库没有跟踪分支的概念:它只是在后端运行pull
时更新其引用。它不关心引用了什么提交;这就是强制推送(git-receive-pack
)存在的原因。事实上,强制推送甚至不是git pack协议中的一个构造,而只是一个客户端选项,用于忽略保持历史完整性的常规检查。推送时,并不意味着需要合并/快进:只意味着更新远程对象数据库及其引用列表。在客户端,只需更新远程跟踪分支以匹配成功推送的内容(无论是否强制)gitpush-f
总而言之:获取需要合并,因为获取的远程跟踪分支必须合并到相应的本地分支中,以便在工作存储库中使用。然而,使用push,您可能不一定需要合并;您只是在更新远程分支。您可能最好在git mailist中询问它,但有一个重要的区别:由pull执行的合并仍然是您个人历史的一部分。您可以测试它,或者更新合并消息,或者在合并之前改变主意并重置为提交。你可以花时间解决冲突 如果git push正在合并,这个自动合并的提交将立即变成p
$ git pull From . * branch lb2 -> FETCH_HEAD Auto-merging file1.txt CONFLICT (content): Merge conflict in file1.txt Automatic merge failed; fix conflicts and then commit the result.
$ git push . lb1:lb2 Total 0 (delta 0), reused 0 (delta 0) To . cdd1247..2dfb555 lb1 -> lb2