0

我通过添加一个新的和删除一个(通过使用 的 Web 界面)对我remote repository的 in进行了两项更改。当我做 :GitHubfileold fileGitHub

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没有工作?

4

1 回答 1

2

这是真的,git pull真的只是git fetchplus git merge。但是有很多警告。

获取

当你运行时:

$ git fetch origin master

这表示”:

$ git fetch origin master:FETCH_HEAD

它告诉git fetch你跑过origin去问他们——github,在这种情况下,我将在这里使用“他们”和“他们”来指代origin,所以“它”的意思是“你的获取”——他们对 branch 有什么master。无论他们拥有什么,它都会带来,但它会将其置于当地的特殊名称之下FETCH_HEAD

如果您改为运行:

$ git fetch origin

这个“手段”是fetch跑过origin去问他们所有的树枝,把它们都当作“偏远的树枝”带过来。如果他们有分支“master”和“experiment”,它会将它们作为“远程分支”origin/masterorigin/experiment.

git 合并

首先,git merge始终合并到您当前的分支*(在输出中标有 a 的分支git branch)。1 换句话说,它知道要合并哪里。不过,您需要告诉它哪里合并。

如果你运行:

$ git merge

没有参数,它必须弄清楚你想要“合并”的提交 ID。它通过查找配置变量merge.defaultToUpstream. 如果你得到:

fatal: No commit specified and merge.defaultToUpstream not set.

这意味着merge.defaultToUpstream未设置,或设置为false而不是true

如果你运行,它会告诉 git merge 要“合并”什么,所以它不需要这个特殊的配置变量。因此:git merge name-or-ID

$ git merge FETCH_HEAD

意思是“找到”指定的提交FETCH_HEAD。或者,如果您运行:

$ git merge origin/master

这意味着“找到由”指定的提交origin/master

重要提示:如果您为 提供多个额外参数git merge,它会执行“章鱼合并”(我不会在此答案中描述)。这意味着它git merge origin mastergit merge origin/master. 斜杠有很大的不同,因为它将merge命令从两个参数合并更改为一个参数合并。(我认为这是不幸的——和/或糟糕的设计——让git pull你完全使用这些论点,但它们的含义与 .) 完全不同git merge。)

把它们放在一起

那么,你想什么时候供应FETCH_HEADgit merge什么时候供应origin/master呢?好吧,回去重新阅读上面关于git fetch的部分。

FETCH_HEAD方法是旧的2方法,在这种方法中,您可以告知git fetch要从中获取的位置和要从中获取的分支,并将git fetch结果写入特殊名称下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 拉

唉,git pull4脚本仍然使用 “pull旧方式”。当您运行时git pull origin master,或者甚至git pull没有参数时,5它最终会运行git fetch origin master,这使得git fetch行为成为“旧方式”。然后它必须使用git merge FETCH_HEAD,因为它只是运行git fetch使得 fetch 没有更新origin/master6


1即使您处于“分离的 HEAD”模式,git merge仍然会合并到您的“当前分支”,有点。只是最接近“当前分支”的东西现在是“分离的 HEAD”。

2或者也许是“传统的”。我希望它是“过时的”,这可能最终会发生,但现在它已经根深蒂固。

3远胜于上。:-)

4我不喜欢git pull。这意味着一种便利,由于它坚持以“旧方式”做事,它最终变得不那么方便,更不用说它长期以来一直存在的一个罕见但严重的错误(在 git 1.8.4 中修复)。

5不带参数,git pull从当前分支的配置中获取远程和分支的名称。例如,如果您在 branch 上,则mastergit 会读取branch.master.remoteandbranch.master.merge来获取originand master。这些是使本地分支master成为“跟踪分支”的相同值,跟踪远程分支origin/master。这很好,除了git pull强制git fetch不更新origin/master。所以git pull更新你的 local master,但留下 git 告诉你现在领先的东西origin/master!呸。(这在 git 1.8.4 中已修复;git fetch现在更新远程分支,即使它写入FETCH_HEAD.)

6这在 git 1.9 中已修复,这可能最终会成为git pull一种实际上很方便的便捷方法。:-)

于 2014-02-03T20:40:22.180 回答