git pull的fetch步骤可能会获取多个远程分支(因为
fetch = +refs/heads/*:refs/remotes/origin/*
).
平原
git fetch
真的很有价值
遥控器的分支(
refs/heads/*
). 但是
git pull
使用
平原
git获取
git获取
一
远程跟踪名称(假设Git版本>=1.8.4).
出于其他原因,这实际上对你的问题的要点并不那么重要,但要说清楚的是,我已经补充了一个(非常)长的描述
git获取
操作和方式
用这个。同时,让我们来解决这个问题
第二
命令
跑。记得,
git拉
本质上是:
-
运行
(有多种选择),然后
-
运行第二个Git命令,通常是
git merge
(有多种选择)。
第一
命令主要收集提交的对象,以及从其他Git存储库中完成这些对象所需的任何内容。在获取之后,您的Git有(一些/足够的)Git的提交,但它们不是的一部分
属于
你的
如果第二个命令是
合并分支
,您的Git运行:
git merge -m
message
hash1
hash2
...
]
merge branch '
B
' of
URL
对某些人来说
B
和一个或多个,但我们希望只有一个提交哈希ID。
任何
合并分支
现在的
分支机构。任何合并:
2
对于正常和快进的情况,结果是当前分支命名为
HEAD
所以答案是:
合并是否也发生在与本地当前分支不对应的其他获取的远程分支上?
是
不
,但问题本身是混乱的,或者至少是混乱的
惯性导航与制导
在它的措辞:合并发生
到
仅限当前分支!因为你只能
退房
仅本地分支机构
地方的
分支永远不会合并到一起。从这个意义上说,合并只能“发生在”本地分支机构。我得猜猜你说的“合并发生在……上”是什么意思。。。“远程分支”(请参阅下面很长的“long”部分,以了解这样的猜测。)
请注意
合并分支
作为论据
一个或多个提交哈希ID。这些其他提交哈希ID
可以
可以通过远程跟踪名称指定,或者作为原始哈希ID指定,或者以Git接受哈希ID的任何其他方式指定,例如相对名称
develop~7^2~3
(尽管我从不推荐这最后一个表达)。这个
git拉
命令始终使用原始哈希ID,但通过
合并分支
的
-m
1
git拉
这是一个设计拙劣的命令:把它想象成一把多刃瑞士军刀,其中几刃永远不能合上,所以每次使用它时,除非你握着它,否则你总是把手掌割断
非常
精致地。多哈希合并通常会导致Git称之为
章鱼合并
,但我不想在这里谈这些血淋淋的细节。这个答案已经太长了。
2
这个
git merge --squash
操作与
git merge --no-commit
,作为
--squash
打开
--不承诺
. 这迫使你做出最后的承诺。有什么特别的
git合并--挤压
当你自己做出承诺时,Git会做出新的承诺,
毕竟不是合并提交
git合并--不提交
.
长
这里的一些诡计是由于
git拉
git获取
. 要理解这一点,我们必须从
真的,深深的
git获取
git获取
这个
git获取
命令是复杂的,很多这种复杂的情况都是由于非常老的Git的工作方式造成的。远古的,原始的吉特人没有
有
远程跟踪名称:没有
origin/master
. 这导致了很多丑陋的东西,所以最终Git的人发明了远程跟踪名称,但是由于向后兼容的原因,他们不能仅仅
远程跟踪名称。这就是很多奇怪的地方。
暂时不用担心,记住这一点
git获取
git ls-remote
. 我鼓励学习Git的人跑步
其他
你的
Git在任何
git获取
.
还要记住调用
git获取
是(简化):
git fetch [<remote> [<refspec1> [<refspec2> ...]]]
这个
remote
通常默认为
origin
但你当然可以直截了当地写出来
起源
. 任何
其他
论据
起源
参考规范
不
提供任何refspec,这样我们就不必定义它们是如何工作的;我们假设您的Git和他们的Git使用的是所谓的智能协议(愚蠢的协议可能会浪费大量时间传输无用的数据,所以我们不要去那里)。最后,我们假设一个标准
fetch =
行,读取
.
这是真实的
git ls远程
输出,微调一位(ok,a
),对于Git的Git存储库:
ecbdaf0899161c067986e9d9d564586d4b045d62 HEAD
0d0ac3826a3bbb9247e39e12623bbcfdd722f24c refs/heads/maint
ecbdaf0899161c067986e9d9d564586d4b045d62 refs/heads/master
2a65cea5f9ce26d22baec1ec541c86d41e2e700a refs/heads/next
855f98be272f19d16564ed44d8e858d8d459d7e5 refs/heads/pu
0596e1ad5143dab167e62bf39387d2b4e06cadb6 refs/heads/todo
d5aef6e4d58cfe1549adef5b436f3ace984e8c86 refs/tags/gitgui-0.10.0
3d654be48f65545c4d3e35f5d3bbed5489820930 refs/tags/gitgui-0.10.0^{}
[massive snippage]
dcba104ffdcf2f27bc5058d8321e7a6c2fe8f27e refs/tags/v2.9.5
4d4165b80d6b91a255e2847583bd4df98b5d54e1 refs/tags/v2.9.5^{}
maint
,
master
,
next
pu
,和
todo
. (他们还给了我们一个推荐的分支机构,让我们通过
头
,以及大约20个bajillion标记的列表以及这些标记标识的提交。)
git fetch
remote
您的Git在某个URL调用其他Git(可能很长,很难键入)URL存储为一个配置条目,使用更短、更简单、更有意义的URL
你到底做了什么
git ls-remote
remote
打印出来。这会给你的Git一个完整的
他们的
Git的分支和标记名。
然后你的Git通过
取回=
线,
您尚未提供任何参考规范。这将为Git提供远程跟踪名称的列表,例如
refs/remotes/origin/master
,以创建或更新。它还提供了Git将要提交的提交散列id的列表
需要
参考/遥控/原点/主
在名称中哈希ID数据库必须提供
有效的
原点/主
,它需要在本地具有哈希ID为的提交(在本例中)
ecbdaf0899161c067986e9d9d564586d4b045d62
此时,您的Git将把这些必需的提交哈希id添加到它需要确保存在的提交列表中。它现在进入对话的“拥有/想要/不要”阶段。
我有哈希ID为H的提交
欲望
,你的Git会说:
是的,请寄给我那个承诺书,并告诉我那个承诺书的父母。
如果你的Git已经
但是,你的Git会说:
不,我根本不需要那个承诺。
做
已经有了,所以你的Git说
对那些人;一旦你的Git拒绝了所有的父母,或者他们的Git已经用完了父母,这两个Git就开始实际的数据传输。
为了完成数据传输,他们的Git现在打包了所有选定的提交(如果有的话,也许您已经有了所有的分支提示提交)和所有必需的子对象,并将它们发送出去,称为
薄包装
. 这是计算密集型的
你的
结束时,您可能会看到更多关于检查连接性之类的消息,但不管怎样,现在您的Git拥有了所有提交,以及完成这些提交所需的所有其他对象。
会话
fetch
linegit将继续更新远程跟踪分支。现在您的Git已经有了必要的提交,Git将替换您的Git的旧值
参考/遥控/原点/主
以及他们的新价值观。每个更新操作:
强制更新是Git将执行的操作,即使更新操作本身不是一个快进操作。快进更新是指
新的
哈希ID保留现有哈希ID
(有关可达性的完整讨论,请参见
Think Like (a) Git
). 所以最后一个阶段尝试更新每个映射的名称。通常,如果需要的话,这是强制的,这样所有这些更新都会完成,而不考虑快进性。你的Git指纹:
<oldhash>..<newhash> master -> master
如果你的Git更新了你的
参考/遥控/原点/主
基于他们的
refs/heads/master
<oldhash>
是您的
参考/遥控/原点/主
以及
<newhash>
是新哈希ID的缩写。
+ <oldhash>...<newhash> master -> master (forced update)
(注意加号和三个点,以及附加说明)如果更新是
不
快进,但还是发生了。
(如果更新不是快进的并且不是强制的,那么Git不会打印任何内容,也不会更新远程跟踪名称。这在实践中从未发生过,因为
取回=
这条线有加号。)
git获取
首先,当然,我们需要定义
参考规范
. 两者
git获取
和
git push
使用它们,尽管它们在细节上有点不同。
refspec非常简单:它们主要是两个名称之间带有冒号的成对名称。前面有一个可选的加号,意思是
力
+refs/heads/master:refs/remotes/origin/master
这和我们在电影里看到的很像
取来
线路。
来源
,右边的是
目的地
. 所以这个refspec的意思是
使用
参考/主管/主管
参考/遥控/原点/主
. 我们会抓到你的
他们的
主人
并且成功了
我们的
原点/主
,如果有必要,我们会强制更新。
refs/heads/
(或对于标签
refs/tags/
猜测
通过检查您的和/或它们的名称的内容,您的意思是分支名称还是标记名称。如果你写的话,这有点草率
master:master
例如,如果
分支
命名
主人
,但同时也是
标签
主人
? 我不知道答案我必须测试才能确定但是我
参考/标题/
我的意思是,不要做一个名为
. :-)
最后,这意味着您将看到refspec
很多。这对于
git获取
:我们不想覆盖
我们的
主人
原点/主
相反。
你也可以用一种
一半
-参考规范:
master
或:
:delete
这意味着更复杂的是
对于
以及
. 与
git推送
,
:delete
是对另一个Git的请求
删除
git获取
,省略源代码完全没有意义(测试表明Git将丢失的源代码解释为
,但我建议不要假设它没有任何文档记录。)
省略
目的地
另一方面,告诉我们
git获取
是吗
. 也就是说,如果您运行:
git fetch origin master
把他们的
主人
,不要碰我的任何分行名称。
你的
,而不是他们的!当然,你可以:
git fetch origin master:newbranch
新的
存储库中名为
newbranch
起源
的
主人
原点/主
git fetch origin master
更新
原点/主
.
git推送
使用与源相同的名称
,所以
git push origin master
方法
git push origin master:master
吉特。不,你用的是
直接!)
自动更新
你的
主人
(假设标准
取回=
行,再次)。在Git版本之前,
git获取源主机
真的把他们的
主人
然后。。。不更新
有什么事吗
.
好吧,那是个谎言,
因为
git获取
总是
自古以来
也
.git/FETCH_HEAD
git拉
回到画面,但首先,让我们完成这个场景。
如果没有参考规范,就服从你的要求
取回=
设置
如果你跑了
git fetch origin
git获取
没有任何参数和Git选择
作为遥控器,Git将使用
设置以决定要获取的内容。通常的设置是“将所有分支名称带过来,并将它们重命名为远程跟踪名称”,这是由标准refspec强制执行的,带有两个星号和前导加号。
另一个有点不正常,但不是疯狂怪异,
取来
git clone --single-branch
. 而不是
+refs/heads/*:refs/remotes/origin/*
,上面写着
+refs/heads/somebranch:refs/remotes/origin/somebranch
. 这就是你克隆的原因
单个分支:
每一个
取来
运行时,不带任何参数,只从Git中的一个分支更新一个远程跟踪名称。还有更奇怪的
取来
线条创建者
git clone --mirror
在这两种正常情况下,一个常规克隆,或者一个分支克隆
git获取
将带来所有或一个分支,并更新所有或一个远程跟踪名称。然后为了保持向后兼容性,Git将更新
.git/取头
,塞进里面
全部的
.git/取头
文件内容根本没有实际用途。
使用refspecs时,请遵守您的refspecs
git获取源主机
. 这给了我们一个机会
参考规范
,你的Git会服从的。你的Git会拿来的
他们的
主人
分支机构。然后你的Git会更新你的
原点/主
自动地,
如果
您的Git至少是1.8.4,因为这样做是明智的,而且
取回=
线路正常。
每一个
即使是一个非常古老的吉特,你的吉特也会
也
.git/取头
只有
没有
更新
原点/主
做
原点/主
再一次
也许是这个
git获取源主机
是由
git拉
git拉
我们现在知道,如果你跑:
git pull
(假设这样做有用),Git将运行
git获取
然后运行第二个命令。如果你跑了
git拉
争论,争论
git获取
那个
git拉
运行来自配置:
$ git config --get-regexp '^branch\.master\.'
branch.master.remote origin
branch.master.merge refs/heads/master
git获取
那个
git拉
git fetch origin refs/heads/master
这个
部分来自
branch.master.remote
refspec实际上就是
branch.master.merge
git获取
,我们现在知道了,会在
分支的提示提交,由于
部分。这反过来会根据需要带来其他主分支提交。我们的Git可能会也可能不会更新我们自己的Git
,这取决于我们的Git版本,但在所有情况下,我们的Git都会
.git/取头
主人
-分支提示提交。
git拉
那么,威尔
把这个杂烩从鱼里弄出来
文件。
这个
是散列ID的来源
git拉
为了我们!有什么更新吗
原点/主
是偶然的
git拉
我们还可以运行:
git pull xyz
在这种情况下,我们的Git将使用
xyz
作为远程名称,但仍将运行:
git pull origin refs/heads/master
因为
设置为
参考/主管/主管
. 所以这次
git获取
将调用下面列出的任何URL
,获取
他们的
,或者更新我们的
refs/remotes/xyz/master
取决于我们的吉特葡萄酒。但我们的Git会再次写信给
.git/取头
实际的
哈希ID
为了他们的利益
主人
,以及我们的
git拉
将此哈希ID传递给
合并分支
我们可以跑:
git pull anyremote foobar
git拉
git fetch anyremote foobar
这将通过我们上面描述的所有花哨的匹配来决定是否要把他们的
refs/heads/foobar
refs/tags/foobar
. 但不管发生什么,如果
一点用都没有,它为
anyremote
的
foobar
,然后我们的
git拉
合并分支
.
git拉
一次又一次地刺伤用户
鉴于用户已经学会运行:
git pull origin master
嘿,如果我能拉大师,为什么我不能拉大师和发展两者?
它们运行:
git pull origin master develop
git拉
不会的。
相反,
跑:
git fetch origin master develop
这个
git获取
命令尽职地召唤
,带来其所需的任何提交
主人
,带来其所需的任何提交
develop
,并可能更新远程跟踪名称,这取决于我们的Git年份。然后我们的
取来
.git/取头
,写在里面
两个哈希ID
.
现在我们的
git拉
跑
只有一个
git merge -m $message $hash1 $hash2
这会产生一个
章鱼合并
我们现在的分部。要获得两个独立的合并,用户
,
git拉
应该
已经完成:
git checkout master && git merge -m $message1 $hash1 &&
git checkout develop && git merge -m $message2 $hash2
两个明显的消息和两个散列。
避免
git拉
. 它做了一些非常令人惊讶的事情。很多程序员都犯了这个错误,早在十多年前Git的早期,我就犯过,还有很多同事也犯过。今天的文档要好得多,所以可能会有更少的用户犯这个错误,但这仍然需要大量的解释才有意义。