如果在GitHub存储库中添加或删除文件,将取/合并不起作用? [英] will fetch/merge not work if files are added or deleted in GitHub repository?
问题描述
我对 GitHub
中的远程存储库
做了两处修改,添加了一个新的文件
并删除旧文件
(通过使用 GitHub
的Web界面)。当我这样做时:
git fetch origin master
remote:计数对象:6,完成。
remote:压缩对象:100%(4/4),完成。
remote:合计5(delta 2),重用0(delta 0)
开箱对象:100%(5/5),完成。
来自github.com:TommyHilly/programFiles
*分支大师 - > FETCH_HEAD
git merge origin / master
已经是最新的。
无论何时添加或删除新文件, git pull
only works( git fetch / merge failed
)。
$ git pull
从github.com:TommyHilly/programFiles
b598c97..531d466 master - >原产地/主人
更新b598c97..531d466
快进
README.txt | 2 ++
a.out | Bin 8496 - > 0字节
2个文件已更改,2个插入(+)
创建模式100644 README.txt
删除模式100755 a.out
但是当我编辑了一些文件(没有新添加或删除)时, git fetch
和合并
工作正常。
我做错了什么或者是如何 git
作品?
编辑:
git remote -v
origin git@github.com:TommyHilly / programFiles.git(fetch)
origin git@github.com:TommyHilly / programFiles.git(push)
$ b $编辑2:只是做
git fetch
和 git merge origin / master
似乎工作。但我不明白发生了什么? 但是 git fetch origin master
后跟 git merge origin / master
无效?
git pull 实际上只是 git fetch
加上 git merge
。但有一些警告。
git fetch
运行时:
$ git fetch origin master
<这个意味着:
$ git fetch origin master:FETCH_HEAD
告诉 git fetch
运行到原点$ c $在这种情况下,我会用他们和他们来引用
origin
,所以it意思是你的获取 - 它们对于分支 master
所具有的。不管他们有什么,它都会带来,但它会在当地特殊名称 FETCH_HEAD
下。
如果您运行相反:
$ git fetch origin
这个意味着用于 fetch
运行到 origin
并询问他们所有他们的分支机构,并将它们全部作为远程分支机构。如果他们有分支主和实验,它会将这些分支作为远程分支 origin / master
和 origin / experiment
$ b
git merge
首先, git merge
始终合并到当前分支中( > git分支$ c中标有< $ c> output)。 1 换句话说,它知道将合并到的位置。但是,您需要告诉它将从 合并到哪里。 如果您运行: b
$ git merge
没有参数,它有找出你想要合并的提交ID。它通过查找配置变量 merge.defaultToUpstream
来完成。如果你得到:
fatal:没有指定commit和merge.defaultToUpstream没有设置。
这意味着 merge.defaultToUpstream
未设置,或设置为 false
而不是 true
。
如果你运行 git merge name-or-id
,它告诉git合并什么以合并,所以它不需要这个特殊的配置变量。因此:
$ git merge FETCH_HEAD
表示查找由 FETCH_HEAD
>指定的提交。或者,如果运行:
$ git merge origin / master
$这意味着找到由
origin / master
>指定的提交。
重要:如果您为
git merge
提供多个额外参数,则会执行章鱼合并(其中I在这个答案中不会描述)。这意味着git merge origin master
与git merge origin / master
完全不同。斜线产生巨大差异,因为它将merge
命令从双参数合并改为单参数合并。 (我认为它是不幸的 - 和/或糟糕的设计 -git pull
你恰好使用这些参数,但它们意味着与不同的东西git merge )
把它们放在一起
所以,你想什么时候提供
FETCH_HEAD
转换为git merge
,您想在何时提供origin / master
取而代之?那么,回头再读一下上面有关 git fetch 的部分。
$ b
FETCH_HEAD
方法是旧的 2 方式,您可以在其中告诉git fetch
要从中提取的位置以及要从中提取的分支,以及在特殊名称FETCH_HEAD
下写入结果git fetch
。不管你提取哪个分支:git fetch origin inigo_montoya
,git fetch origin you_killed_my_father
,git fetch origin不可思议
:它们全都过来并重新命名为FETCH_HEAD
,所以这就是你合并的内容。
origin / master
方法是新的 3 方式:运行git fetch origin
,它只是带来一切,您可以花时间浏览远程分支机构。一旦你对origin / master
感到满意,并准备好合并它,你可以通过它的(清晰,简单,明显)名称来合并它,而不是通过FETCH_HEAD
。
git pull
唉,
git pull
。 4pull
脚本仍然使用旧方式。当你运行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
仍然会合并到您的当前分支中。只是最接近当前分支的是现在的分离头。
2 或者也许是传统。我希望它是过时的,而且最终可能会发生这种情况,但现在它已经深入人心。
3 而且远胜于上。 : - )
4 我不喜欢
git pull
。它意味着一种方便,并且由于坚持以旧方式来做事,所以它变得不那么方便,更不用说了一个罕见但严重的错误很长一段时间(固定在git 1.8中。 4)
$ b5 不带参数,
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中得到了解决;即使它写入到FETCH_HEAD
中,git fetch
6 这个问题已经在git 1.9中解决了,它最终可能会使
git pull
一种方便的方法,它实际上很方便。 : - )I made two changes to my
remote repository
inGitHub
, by adding a newfile
and deleting aold file
(by using the Web interface ofGitHub
). when I do :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.
whenever new files are added or deleted,
git pull
only works (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
But when I have some files edited (nothing new added or deleted),
git fetch
andmerge
works fine.Am I doing something wrong or is this how
git
works?EDIT:
git remote -v origin git@github.com:TommyHilly/programFiles.git (fetch) origin git@github.com:TommyHilly/programFiles.git (push)
EDIT 2: Just doing
git fetch
andgit merge origin/master
seems to work. But I dont understand what is going on?But
git fetch origin master
followed bygit merge origin/master
did not work?解决方案It's true that
git pull
is really justgit fetch
plusgit merge
. But there are a bunch of caveats.git fetch
When you run:
$ git fetch origin master
this "means":
$ git fetch origin master:FETCH_HEAD
which tells
git fetch
to run over toorigin
and ask them—github, in this case, and I will use "them" and "they" here to refer toorigin
, so that "it" means "your fetch"—what they have for branchmaster
. Whatever they have, it brings over, but it puts that under the local special nameFETCH_HEAD
.If you run instead:
$ git fetch origin
this "means" for
fetch
to run over toorigin
and ask them about all their branches, and bring them all over as "remote branches". If they have branches "master" and "experiment", it brings those over as "remote branches"origin/master
andorigin/experiment
.git merge
First,
git merge
always merges into your current branch (the one marked with a*
ingit branch
output).1 In other words, it knows where to merge to. You need to tell it where to merge from, though.If you run:
$ git merge
with no arguments, it has to figure out what commit-ID you want to "merge from". It does this by looking for a configuration variable,
merge.defaultToUpstream
. If you get:fatal: No commit specified and merge.defaultToUpstream not set.
this means
merge.defaultToUpstream
is not set, or is set tofalse
instead oftrue
.If you run
git merge name-or-ID
, that tells git merge what to "merge from", so it does not need this special configuration variable. Hence:$ git merge FETCH_HEAD
means "find the commit specified by
FETCH_HEAD
". Or, if you run:$ git merge origin/master
this means "find the commit specified by
origin/master
".Important: If you supply more than one extra argument to
git merge
, it does an "octopus merge" (which I'm not going to describe in this answer). This means thatgit merge origin master
is quite different fromgit merge origin/master
. The slash makes a huge difference, because it changes themerge
command from a two-argument merge, to a one-argument merge. (I think it's unfortunate—and/or bad design—thatgit pull
has you use exactly those arguments, but they mean something quite different togit merge
.)Putting them together
So, when do you want to supply
FETCH_HEAD
togit merge
, and when do you want to supplyorigin/master
instead? Well, go back and re-read the section about git fetch above.The
FETCH_HEAD
method is the old2 way, in which you tellgit fetch
both the place to fetch from, and the branch to fetch from, and havegit fetch
write the result under the special nameFETCH_HEAD
. It does not matter what branch you fetched:git fetch origin inigo_montoya
,git fetch origin you_killed_my_father
,git fetch origin inconceivable
: they all come over and get renamedFETCH_HEAD
, so that's what you merge with.The
origin/master
method is the new3 way: you rungit fetch origin
and it just brings everything over and you can take your time and browse through "remote branches" at your leisure. Once you're happy withorigin/master
and ready to merge it in, you merge it in by its (clear, simple, and obvious) name, instead of byFETCH_HEAD
.git pull
Alas,
git pull
.4 Thepull
script still uses the "old way". When you rungit pull origin master
, or even justgit pull
with no arguments,5 it winds up runninggit fetch origin master
, which makesgit fetch
behave the "old way". Then it usesgit merge FETCH_HEAD
, which it has to, because it's just rungit fetch
such that fetch did not updateorigin/master
.6
1Even if you're in the "detached HEAD" mode,
git merge
still merges to your "current branch", sort of. It's just that the closest thing to "current branch" is now "the detached HEAD".2Or maybe "traditional". I wish it were "obsolete", and that might happen eventually, but for now it's pretty deeply rooted.
3And far superior. :-)
4I don't like
git pull
. It's meant as a convenience, and due to its insistence on doing things the "old way", it winds up being less convenient, not to mention one rare but serious bug it's had for a long time (fixed in git 1.8.4).5With no arguments,
git pull
gets the name of the remote and branch from the configuration for the current branch. If you're on branchmaster
, for instance, git readsbranch.master.remote
andbranch.master.merge
to getorigin
andmaster
. These are the same values that make local branchmaster
a "tracking branch", tracking remote-branchorigin/master
. Which is great, exceptgit pull
forcesgit fetch
not to updateorigin/master
. Sogit pull
updates your localmaster
, but leaves things such that git tells you you're now ahead oforigin/master
! Yuck. (This is fixed in git 1.8.4;git fetch
updates remote branches now, even while it writes toFETCH_HEAD
.)6This is fixed in git 1.9, which might finally make
git pull
a convenience method that's actually convenient. :-)这篇关于如果在GitHub存储库中添加或删除文件,将取/合并不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!