'git pull origin mybranch' 使本地 mybranch N 在原点之前提交。为什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1741143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
'git pull origin mybranch' leaves local mybranch N commits ahead of origin. Why?
提问by Matthias
I just observed something odd about git pull
, which I don't understand.
我只是观察到一些奇怪的事情git pull
,我不明白。
On Friday, I worked on a local branch. let's call it mybranch
. Before leaving the office I pushed it to origin (which is my github repo): git push origin mybranch
.
星期五,我在当地的一家分公司工作。让我们称之为mybranch
。在离开办公室之前,我把它推到原点(这是我的GitHub库)git push origin mybranch
。
Yesterday at home, I pull
ed mybranch to my laptop, did some more coding, and then pushed my changes back to github (origin).
昨天在家里,我将pull
mybranch 编辑到我的笔记本电脑上,做了更多的编码,然后将我的更改推送回 github(原点)。
Now I'm at work again, and tried to pull the changes from yesterday to my work machine (I didn't change anything in my work place's local repo over the weekend):
现在我又开始工作了,并试图将昨天的更改拉到我的工作机器上(周末我没有在工作场所的本地存储库中更改任何内容):
git pull origin mybranch
that caused a fast forward merge, which is fine. I then did a git status
, and it said:
这导致了快进合并,这很好。然后我做了一个git status
,它说:
# On branch mybranch
# Your branch is ahead of 'origin/mybranch' by 6 commits.
#
nothing to commit (working directory clean)
Huh? How can it be 6 commits ahead when I didn't even touch it over the weekend, AND just pulled from origin? So I ran a git diff origin/mybranch
and the diffs were exactly the 6 changes I just pulled from remote.
嗯?当我在周末甚至没有触及它时,它怎么可能提前 6 次提交,并且只是从原点拉出?所以我运行了一个git diff origin/mybranch
,差异正是我刚刚从远程提取的 6 个更改。
I could only "fix" this by running git fetch origin
:
我只能通过运行来“修复”这个git fetch origin
:
From [email protected]:me/project
af8be00..88b0738 mybranch -> origin/mybranch
Apparently, my local repo was missing some reference objects, but how can that be? I mean, a pull does a fetch already, and I didn't work on anything except that branch, so a git fetch origin
and git fetch origin mybranch
should have the same result?
显然,我的本地存储库缺少一些参考对象,但这怎么可能?我的意思是,pull 已经进行了 fetch,除了那个分支我没有做任何事情,所以 a git fetch origin
andgit fetch origin mybranch
应该有相同的结果?
Should I always use git pull origin
instead of git pull origin branchname
?
我应该总是使用git pull origin
而不是git pull origin branchname
吗?
I'm confused.
我糊涂了。
回答by CB Bailey
git pull
calls git fetch
with the appropriate parameters before merging the explicitly fetched heads (or if none the remote branch configured for merge) into the current branch.
git pull
git fetch
在将显式获取的头(或者如果没有配置为合并的远程分支)合并到当前分支之前,使用适当的参数调用。
The syntax: git fetch <repository> <ref>
where <ref>
is just a branch name with no colon is a 'one shot' fetch that doesn't do a standard fetch of all the tracked branches of the specified remote but instead fetches just the named branch into FETCH_HEAD
.
语法:git fetch <repository> <ref>
where<ref>
只是一个没有冒号的分支名称是“一次性”提取,它不会对指定远程的所有跟踪分支进行标准提取,而是仅将命名分支提取到FETCH_HEAD
.
Update:for Git versions since 1.8.4, if there is a remote tracking branch which tracks the ref that you asked to fetch then the tracking branch will now be updated by fetch
. This change has been made specifically to avoid the confusion that the previous behaviour caused.
更新:对于自 1.8.4 以来的 Git 版本,如果有一个远程跟踪分支跟踪您要求获取的引用,那么跟踪分支现在将被更新fetch
。进行此更改是为了避免之前的行为造成的混淆。
When you perform git pull <repository> <ref>
, FETCH_HEAD
is updated as above, then merged into your checked out HEAD
but none of the standard tracking branches for the remote repository will be updated (Git <1.8.4). This means that locally it lookslike you are ahead of of the remote branch, whereas in fact you are up to date with it.
当您执行git pull <repository> <ref>
,FETCH_HEAD
如上所述更新,然后合并到您的检出中,HEAD
但远程存储库的任何标准跟踪分支都不会更新(Git <1.8.4)。这意味着在本地看起来您领先于远程分支,而实际上您是最新的。
Personally I always do git fetch
followed by git merge <remote>/<branch>
because I get to see any warnings about forced updates before I merge, and I can preview what I'm merging in. If I used git pull
a bit more than I do, I would do a plain git pull
with no parameters most of the time, relying on branch.<branch>.remote
and branch.<branch>.merge
to 'do the right thing'.
就我个人而言,我总是git fetch
遵循,git merge <remote>/<branch>
因为我在合并之前会看到任何关于强制更新的警告,并且我可以预览我正在合并的内容。如果我使用git pull
的比我多一点,我会做一个git pull
没有参数的平原的时候,依靠branch.<branch>.remote
并branch.<branch>.merge
“做正确的事”。
回答by VonC
What does git remote -v show
returns when it comes to origin?
什么是git remote -v show
原产地退货?
If origin points to github, the status should be up to date, and not ahead of any remote repo. At least, with the Git1.6.5 I am using for a quick test.
如果 origin 指向 github,则状态应该是最新的,而不是在任何远程仓库之前。至少,我使用 Git1.6.5 进行快速测试。
Anyway, to avoid this, define explicitly the remote repo of master branch:
无论如何,为了避免这种情况,明确定义 master 分支的远程仓库:
$ git config branch.master.remote yourGitHubRepo.git
then a git pull origin master
, followed by a git status
should return a clean status (no ahead).
Why? because the get fetch origin master (included in the git pull origin master) would not just update FETCH_HEAD
(as Charles Baileyexplains in his answer), but it would alsoupdate the "remote master branch" within your local Git repository.
In that case, your local master would not seem anymore to be "ahead" of the remote master.
然后 a git pull origin master
,后跟 agit status
应该返回一个干净的状态(没有提前)。
为什么?因为 get fetch origin master(包含在 git pull origin master 中)不仅会更新FETCH_HEAD
(正如Charles Bailey在他的回答中解释的那样),而且还会更新本地 Git 存储库中的“远程主分支”。
在这种情况下,您的本地主站似乎不再“领先”于远程主站。
I can test this, with a git1.6.5:
我可以用 git1.6.5 测试一下:
First I create a workrepo:
首先我创建一个workrepo:
PS D:\git\tests> cd pullahead
PS D:\git\tests\pullahead> git init workrepo
Initialized empty Git repository in D:/git/tests/pullahead/workrepo/.git/
PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo firstContent > afile.txt
PS D:\git\tests\pullahead\workrepo> git add -A
PS D:\git\tests\pullahead\workrepo> git commit -m "first commit"
I simulate a GitHub repo by creating a bare repo (one which can receive push from anywhere)
我通过创建一个裸仓库来模拟一个 GitHub 仓库(一个可以从任何地方接收推送的仓库)
PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone --bare workrepo github
I add a modif to my working repo, that I push to github repo (added as a remote)
我在我的工作仓库中添加了一个 modif,我推送到 github 仓库(添加为远程)
PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo aModif >> afile.txt
PS D:\git\tests\pullahead\workrepo> git ci -a -m "a modif to send to github"
PS D:\git\tests\pullahead\workrepo> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo> git push github
I create a home repo, cloned of GitHub, in which I make a couple of modifications, pushed to GitHub:
我创建了一个从 GitHub 克隆的家庭存储库,在其中进行了一些修改,然后推送到 GitHub:
PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone github homerepo
PS D:\git\tests\pullahead> cd homerepo
PS D:\git\tests\pullahead\homerepo> type afile.txt
firstContent
aModif
PS D:\git\tests\pullahead\homerepo> echo aHomeModif1 >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a first home modif"
PS D:\git\tests\pullahead\homerepo> echo aHomeModif2 >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a second home modif"
PS D:\git\tests\pullahead\homerepo> git push github
I then clone workrepo for a first experiment
然后我克隆 workrepo 进行第一个实验
PS D:\git\tests\pullahead\workrepo4> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo2
Initialized empty Git repository in D:/git/tests/pullahead/workrepo2/.git/
PS D:\git\tests\pullahead> cd workrepo2
PS D:\git\tests\pullahead\workrepo2> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo2> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
* branch master -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
afile.txt | Bin 46 -> 98 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
In that repo, git status does mention master geing ahead of 'origin
':
在那个 repo 中, git status 确实提到了 master geing 领先于 ' origin
':
PS D:\git\tests\pullahead\workrepo5> git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)
But that is only origin
is not github:
但这只是origin
不是 github:
PS D:\git\tests\pullahead\workrepo2> git remote -v show
github d:/git/tests/pullahead/github (fetch)
github d:/git/tests/pullahead/github (push)
origin D:/git/tests/pullahead/workrepo (fetch)
origin D:/git/tests/pullahead/workrepo (push)
But if I repeat the sequence in a repo which has an origin to github (or no origin at all, just a remote 'github' defined), status is clean:
但是,如果我在具有 github 起源的 repo 中重复序列(或根本没有起源,只是定义了一个远程“github”),则状态是干净的:
PS D:\git\tests\pullahead\workrepo2> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo4
PS D:\git\tests\pullahead> cd workrepo4
PS D:\git\tests\pullahead\workrepo4> git remote rm origin
PS D:\git\tests\pullahead\workrepo4> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo4> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
* branch master -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
afile.txt | Bin 46 -> 98 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
PS D:\git\tests\pullahead\workrepo4> git status
# On branch master
nothing to commit (working directory clean)
If I had only origin
pointing on github
, status
would be clean for git1.6.5.
It may be with a 'ahead' warning for earlier git, but anyway, a git config branch.master.remote yourGitHubRepo.git
defined explicitly should be able to take care of that, even with early versions of Git.
如果我只origin
指向github
, status
git1.6.5 就很干净了。
对于早期的 git,它可能带有“提前”警告,但无论如何,git config branch.master.remote yourGitHubRepo.git
明确定义的应该能够解决这个问题,即使是早期版本的 Git。
回答by Pat Notz
Are you careful to add all of your remote (except origin
which comes with your original clone) using git remote add NAME URL
? I've seen this bug when they've just been added to the git config.
您是否小心origin
使用git remote add NAME URL
?添加所有遥控器(原始克隆附带的除外)?当它们刚刚添加到 git 配置时,我已经看到了这个错误。