在处理功能分支时,我使用此Git命令将我的"develop"分支更新为最新状态,在将我的功能分支与"develop"合并之前:
git fetch origin develop:develop
Run Code Online (Sandbox Code Playgroud)
这是有效的,即本地"开发"指向与"原点/开发"相同的提交,并且处于最新的起源状态.
不知何故,当检查"develop"分支时,此命令失败:
fatal: Refusing to fetch into current branch refs/heads/develop of non-bare repository
fatal: The remote end hung up unexpectedly
Run Code Online (Sandbox Code Playgroud)
如果我知道为什么会发生这种情况,那将有助于我更好地理解Git.
Von*_*onC 16
错误消息来自builtin/fetch.c#check_not_current_branch().
该功能一直回到8ee5d73,2008年10月,git 1.6.0.4
评论很有启发性:
一些令人困惑的教程表明,以这样的方式获取当前分支是个好主意:
git fetch origin master:master
Run Code Online (Sandbox Code Playgroud)
(或者更糟糕的是:使用"pull"而不是"fetch"的相同命令行).
虽然存储你想要的内容可能是有意义的,但当前分支是"master" 时通常是完全错误的.
只有当(不正确的)"git pull origin master:master"尝试通过给予--update-head-ok底层"git fetch" 来解决时才允许这样做,否则我们应该拒绝它,但是在某些地方我们就失去了这种行为.现在,对当前分支的检查仅在非裸存储库中执行,这是对原始行为的改进.
考虑到函数check_not_current_branch()被调用:
if (!update_head_ok)
check_not_current_branch(ref_map);
Run Code Online (Sandbox Code Playgroud)
这意味着git fetch -u origin develop:develop应该工作.
-u
--update-head-ok
Run Code Online (Sandbox Code Playgroud)
默认情况下,git fetch拒绝更新与当前分支对应的头部.此标志禁用检查.
这纯粹是为了与内部git pull沟通git fetch,除非你实施自己的瓷器,否则你不应该使用它.
即使您不应该使用该选项,它也会回答您的初始要求,使" git fetch origin branch:branch"在当前分支上工作.
关于这个补丁的来源,请按照那里的讨论.
虽然存储你想要的东西可能是有意义的
这是fetch部分:它存储更新的远程历史记录origin/master.
但是,当前的本地分支也是如此master.
正如这个答案中提到的:
我认为"
git fetch url side:master"master当前分支何时被忽略--update-head-ok.
测试在当前失败master.它也无法更新工作目录,并且会将索引保留为删除所有内容.
请参阅" git pull使用refspec "作为示例.
torek展示了一个例子:
假设我用git取并在两个新的提交,我将标签带来的
C和D.
C的父母是A,而且D是以前的节点B:
C
/
...--o--o--A <-- master
\
o--B <-- develop
\
D
Run Code Online (Sandbox Code Playgroud)
这个git fetch的输出会将其列为:
Run Code Online (Sandbox Code Playgroud)aaaaaaa..ccccccc master -> origin/master + bbbbbbb...ddddddd develop -> origin/develop (forced update)
如果您当前的分支不是, 那么强制更新可能就是您想要的develop.
但是如果你在 develop键入时打开git fetch origin develop:develop,并且如果允许获取更新HEAD,那么...那么你当前的索引会反映出来D,而不再是B.
因此git diff,在您的工作树中完成将显示您的文件之间的差异D,而不是之前的HEAD B.
这很糟糕,因为您的初始git checkout develop创建了一个与BHEAD文件相同的工作树.
即使你git status是干净的(没有任何修改),如果git fetch origin develop:develop更新HEAD(强制从B更新到D),git status现在会报告在获取之前没有的差异.
这就是为什么默认情况下git fetch拒绝更新与当前分支对应的头部的原因.