Git 如果我们从本地到远程推送一个提交,它是分支提交X和功能提交Y的合并,但在远程提交Y中不存在,它会工作吗?

Git 如果我们从本地到远程推送一个提交,它是分支提交X和功能提交Y的合并,但在远程提交Y中不存在,它会工作吗?,git,branching-and-merging,git-push,Git,Branching And Merging,Git Push,我正试图了解这种情况 at T1 Local | at T1 Remote: ------------------------------------------------------------------------ E--F featureOne | E--F featureOne / | / A

我正试图了解这种情况

at T1 Local                         |       at T1 Remote:
------------------------------------------------------------------------
 E--F featureOne                    |        E--F featureOne
/                                   |       /
A--B--C--D branchOne                |       A--B--C--D branchOne
------------------------------------------------------------------------


at T2 Local                         |       at T2 Remote:
------------------------------------------------------------------------
merged branchOne into featureOne:   |
   E------F   featureOne            |    E--F featureOne    
  /        \                        |   /       
 /          G                       |   A--B--C--D branchOne                    
/          /                        |               
A--B--C----D branchOne              |                           
------------------------------------------------------------------------


at T3 Local                         |       at T3 Remote:
------------------------------------------------------------------------
merged featureOne into branchOne    |
after git pull branchOne            |
from Remote:                        |
   E------F                         |    E--F featureOne    
  /        \                        |   /       
 /          G-. featureOne          |   A--B--C--D branchOne                    
/          /   \                    |               
A--B--C----D-----H branchOne        |                           
------------------------------------------------------------------------
本地中的H是featureOne的G和branchOne的D之间提交的合并。因为在remote中我们没有G,如果我将branchOne从本地推到远程(origin/branchOne),那么在T4会发生什么呢?它会合并吗?
不幸的是,我无法尝试这样做,因为我先将G从本地featureOne推到远程featureOne,然后将H从本地branchOne推到远程branchOne。

git push所做的是将您提交的部分或全部(或有时不提交)提交给其他git,然后让另一个Git将他们的一些名字设置为某个提交哈希ID

因此,如果你有:

在您的存储库中,无论您的任何分支名称指向何处,并且您告诉您的Git向其他Git发送commit
H
,您的Git都会调用其他Git并提供commit
H

(注意:这里我假设commit
G
F
D
的合并。您的问题描述清楚地表明了这一点。我自己绘制的图表有点不同;请参见下文。)

(如果您明确要求Git向他们发送commit
G
,同样的推理也适用,但在这种特殊情况下,您的Git必须在提供
H
并让他们接受后提供
G
,因此我们只需在这里担心
H
。另外,您询问了关于
Git push branchOne
,您的名字是
分支一个
指向提交
H

如果他们有commit
H
,git推送的这一部分就完成了。在这种情况下,他们没有commit
H
,所以你的git将提供commit
G
D
,因为它们是
H
的父母。如果他们有这些提交,git推送的这一部分就完成了:你的git发送commit
H
(仅限)。如果它们缺少一个或多个提交,您的Git将提供[剩余的]
G
和/或
D
的父级,即
F
C
。如果他们有这些提交,则完成
git推送的这一部分:git发送提交
H
,并根据需要提交
G
和/或
D

让我们看看他们有什么:

这不是正确的拼写,应该是:

git push origin branchOne
origin
部分是告诉您的Git要调用的其他Git的方式。名称部分
branchOne
是这种替代拼写的缩写:

git push origin branchOne:branchOne
冒号
字符的左侧是Git如何找到要提供的开始提交。在本例中,您的名字
branchOne
指向您的提交
H
,因此这就是Git开始提供的提交

冒号的右侧
字符提供了您要求他们在Git存储库中设置的分支名称。通过在此处使用
branchOne
,您将要求他们将名称
branchOne
设置为指向提交
H

它会合并吗

git push
命令从不导致任何合并。它只发送您已有的、他们没有的现有提交,然后要求他们设置一些名称(通常是分支名称)。由他们的git接受或拒绝设置分支名称的请求

如果您正在推送到GitHub,并且有人在GitHub上的Git存储库中的分支名称
branchOne
上启用了“受保护的分支”模式,他们将拒绝更改名称的尝试,因为该分支受保护

但是,在大多数情况下,他们会接受此更改名称的请求。他们当前有自己的名称
branchOne
标识commit
D
。commit
H
将commit
D
作为祖先,实际上是直接父级,因此此操作是快进的(不是快进合并,只是快进),这使请求可以接受

请注意,这根本不要求他们设置自己的名称
featureOne
。他们的名称
featureOne
将继续指向之前指向的任何位置,例如提交
F
。出于StackOverflow过账的目的,我将得出如下结论:

    E------F   <-- featureOne
   /        \
  /          G-.
 /          /   \
A--B--C----D-----H   <-- branchOne
您可以在左侧使用任意提交说明符。这可以是分支名称、标记名称、名称
HEAD
、相对名称(如
master~3
)和reflog条目(如
develope@{dayed})
,甚至是原始散列ID。如果您使用左侧的原始散列ID,并且希望另一个Git创建新的分支名称,则必须拼出全名:

git push origin a123456:refs/heads/new-branch
缩写如下:

git push origin a123456:existing-branch
依赖于他们的Git将名称
现有分支
匹配到他们的一个现有分支名称

如果使用无冒号表单,则必须使用名称,因为该名称需要发送到另一个Git

您可以一次推送多件物品:

git push origin master dev feature
或:

假设名称
新临时分支
在Git的
原点
中尚不存在,则此最新版本使用一个相对名称(
master~3
)创建名为
new temp branch
的新分支。它使用一个无冒号表达式发送本地
dev
分支的提示提交,并请求它们相应地创建或更新其分支名称
dev
。它使用原始哈希ID(
a123456
)请求他们创建或更新他们的标记名
v1.2
。标记名更新通常是禁止的,1因此我们希望这会创建一个新的标记名



1在1.8.2或1.8.4之前的Git版本中存在一个错误,它意外地允许使用与分支名称更新相同的规则进行非强制标记名称更新。

感谢您的简单解释和更正
git push origin <commit-specifier>:<name>
git push origin a123456:refs/heads/new-branch
git push origin a123456:existing-branch
git push origin master dev feature
git push origin master~3:refs/heads/new-temp-branch dev a123456:refs/tags/v1.2