我在remote repository
中对GitHub
进行了两项更改,添加了新的file
并删除了old file
(使用GitHub
的网络界面)。当我这样做时:
git fetch origin master
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From github.com:TommyHilly/programFiles
* branch master -> FETCH_HEAD
git merge origin/master
Already up-to-date.
每当添加或删除新文件时,git pull
仅有效(git fetch/merge fails
)。
$git pull
From github.com:TommyHilly/programFiles
b598c97..531d466 master -> origin/master
Updating b598c97..531d466
Fast-forward
README.txt | 2 ++
a.out | Bin 8496 -> 0 bytes
2 files changed, 2 insertions(+)
create mode 100644 README.txt
delete mode 100755 a.out
但是当我编辑了一些文件(没有添加或删除任何新内容)时,git fetch
和merge
工作正常。
我做错了什么或这是git
的工作原理?
编辑:
git remote -v
origin git@github.com:TommyHilly/programFiles.git (fetch)
origin git@github.com:TommyHilly/programFiles.git (push)
编辑2:
只是做git fetch
和git merge origin/master
似乎有效。但我不明白发生了什么事?
但git fetch origin master
后跟git merge origin/master
无法正常工作?
答案 0 :(得分:2)
git pull
确实只是git fetch
加上git merge
。但是有一些警告。
当你跑步时:
$ git fetch origin master
这“意思是”:
$ git fetch origin master:FETCH_HEAD
告诉git fetch
转到origin
并询问他们-github,在这种情况下,我会在这里使用“他们”和“他们”来引用origin
,所以“它”意味着“你的获取” - 他们对分支master
的意义。无论它们有什么,它都会带来,但它会将其置于本地特殊名称FETCH_HEAD
下。
如果你改为运行:
$ git fetch origin
这意味着fetch
可以转到origin
并向他们询问所有他们的分支机构,并将它们作为“远程分支机构”全部带来。如果他们有分支“主”和“实验”,它会将这些分支作为“远程分支”origin/master
和origin/experiment
。
首先,git merge
始终合并到您的当前分支(*
输出中标有git branch
的那个分支。 1 换句话说,它知道将合并到的位置。但是,您需要告诉它从合并的位置。
如果你跑:
$ git merge
没有参数,它必须弄清楚你想要“合并”的提交ID。它通过查找配置变量merge.defaultToUpstream
来实现此目的。如果你得到:
fatal: No commit specified and merge.defaultToUpstream not set.
这意味着merge.defaultToUpstream
未设置,或设置为false
而不是true
。
如果你运行git merge name-or-ID
,那就告诉git merge要“合并”的内容,所以它不需要这个特殊的配置变量。因此:
$ git merge FETCH_HEAD
表示“查找FETCH_HEAD
指定的提交”。或者,如果您运行:
$ git merge origin/master
这意味着“找到origin/master
指定的提交。”
重要:如果您向git merge
提供多个额外参数,它会执行“章鱼合并”(我在此答案中不会描述)。这意味着git merge origin master
与git merge origin/master
完全不同。斜杠产生了巨大的差异,因为它将merge
命令从双参数合并更改为单参数合并。 (我认为这是不幸的 - 和/或糟糕的设计 - git pull
你确实使用了那些参数,但它们意味着与git merge
完全不同的东西。)
那么,您希望何时向FETCH_HEAD
提供git merge
,以及何时需要提供origin/master
?好吧,请回过头来重新阅读上面关于 git fetch 的部分。
FETCH_HEAD
方法是旧的 2 方式,您可以在其中告诉git fetch
要获取的位置和要从中获取的分支,并且git fetch
1}}以特殊名称FETCH_HEAD
写下结果。您提取的分支无关紧要:git fetch origin inigo_montoya
,git fetch origin you_killed_my_father
,git fetch origin inconceivable
:它们都会过来并重命名为FETCH_HEAD
,这就是您合并的内容。
origin/master
方法是新的 3 方式:您运行git fetch origin
并且它只会带来所有,您可以花时间和在闲暇时浏览“远程分支”。一旦您对origin/master
感到满意并准备将其合并,就可以通过其(清晰,简单,明显)名称将其合并,而不是FETCH_HEAD
。
唉,git pull
。 4 pull
脚本仍然使用“旧方式”。当您运行git pull origin master
,或者甚至只是git pull
没有参数时, 5 它会运行git fetch origin master
,这会使git fetch
表现为“旧”办法”。然后它使用了git merge FETCH_HEAD
,因为它只是运行git fetch
,因此fetch不会更新origin/master
。 6
1 即使您处于“分离的HEAD”模式,git merge
仍会合并到您的“当前分支”。只是最接近“当前分支”的东西现在是“独立的HEAD”。
2 或者也许是“传统的”。我希望它“过时”,并且最终可能会发生,但是现在它已经根深蒂固了。
3 远远优越。 : - )
4 我不喜欢git pull
。这是一种方便,并且由于坚持以“旧方式”做事,它很容易少方便,更不用说one rare but serious bug它已经有很长一段时间了(修复了)在git 1.8.4)。
5 如果没有参数,git pull
将从当前分支的配置中获取远程和分支的名称。例如,如果你在分支master
上,git会读取branch.master.remote
和branch.master.merge
来获取origin
和master
。这些值使本地分支master
成为“跟踪分支”,跟踪远程分支origin/master
。除了git pull
强制git fetch
不更新origin/master
之外,这很棒。因此git pull
更新了您的本地master
,但留下了git告诉您现在提前 origin/master
的内容!呸。 (这在git 1.8.4中得到修复; git fetch
现在更新远程分支,即使它写入FETCH_HEAD
。)
6 这在git 1.9中得到修复,最终可能使git pull
成为实际上方便的便捷方法。 : - )