'git pull origin mybranch'留下本地mybranch N提交原点之前提交。 为什么?
我只是观察到一些关于git pull
东西,我不明白。
星期五,我在当地的一家分店工作。 让我们称之为mybranch
。 在离开办公室之前,我把它推到了原点(这是我的github回购): git push origin mybranch
。
昨天在家里,我pull
我的笔记本电脑pull
我的笔记本电脑上,做了一些更多的编码,然后把我的修改推回给github(原籍)。
现在我又在工作了,并且试图从昨天把改变拉到我的工作机器上(周末我在工作场所的本地回购中没有改变任何东西):
git pull origin mybranch
这导致了一个快速的前进合并,这很好。 然后我做了一个git status
,它说:
# On branch mybranch # Your branch is ahead of 'origin/mybranch' by 6 commits. # nothing to commit (working directory clean)
咦? 当我连周末都没有碰到它的时候,怎么可能会提前6分钟,刚从原点拉出来呢? 所以我运行了一个git diff origin/mybranch
,差异恰恰是我从远程获取的6个变化。
我只能通过运行git fetch origin
“解决”这个问题:
From git@github.com:me/project af8be00..88b0738 mybranch -> origin/mybranch
显然,我的本地回购是缺less一些参考对象,但怎么可能呢? 我的意思是,拉已经提取了,除了那个分支我什么都没有做,所以一个git fetch origin
和git fetch origin mybranch
应该有相同的结果?
我应该总是使用git pull origin
而不是git pull origin branchname
?
我很困惑。
git pull
在合并明确提取的头之前(或者如果没有configuration合并的远程分支)到当前分支之前,用合适的参数调用git fetch
。
语法: git fetch <repository> <ref>
其中<ref>
只是一个没有冒号的分支名称,是一次性提取,不会对指定远程的所有跟踪分支执行标准提取,而是取回只是命名分支到FETCH_HEAD
。
更新:对于自1.8.4以来的Git版本,如果有一个远程跟踪分支跟踪你要求提取的引用,那么跟踪分支现在将通过fetch
进行更新。 这个改变是为了避免以前的行为造成的混乱。
当你执行git pull <repository> <ref>
, FETCH_HEAD
被更新如上,然后被合并到你签出的HEAD
但远程仓库的标准跟踪分支都不会被更新(Git <1.8.4)。 这意味着在本地它看起来像是在远程分支之前,而实际上你已经和它保持同步了。
就个人而言,我总是做git fetch
后面跟着git merge <remote>/<branch>
因为我在合并之前看到有关强制更新的任何警告,我可以预览我正在合并的东西。如果我用git pull
了更多比我做的,我会做大部分时间没有参数的普通的git pull
,依靠branch.<branch>.remote
和branch.<branch>.merge
到'做正确的事情'。
git remote -v show
什么时候返回来源?
如果origin指向github,状态应该是最新的,而不是任何远程repo。 至less,我用Git1.6.5进行了一个快速testing。
无论如何,为了避免这种情况,明确定义主分支的远程回购:
$ git config branch.master.remote yourGitHubRepo.git
那么一个git pull origin master
,随后一个git status
应该返回一个干净的状态(不提前)。
为什么? 因为get fetch origin master(包含在git pull origin master中)不会更新FETCH_HEAD
(正如Charles Bailey在他的答案中所解释的),但它也会更新本地Git存储库中的“remote master branch”。
在这种情况下,你的本地主人似乎不再是远在主人的“前面”了。
我可以用git1.6.5来testing这个:
首先我创build一个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"
我通过创build一个裸回购(可以从任何地方接收推送)来模拟GitHub回购。
PS D:\git\tests\pullahead\workrepo> cd .. PS D:\git\tests\pullahead> git clone --bare workrepo github
我添加一个修改到我的工作回购,我推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
我创build了一个家庭回购,克隆了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
然后我克隆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(-)
在这个回购中,git的地位确实提到了“ 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)
但是,这只是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)
但是如果我在一个有Github的起源的回购中重复序列(或者根本没有起源,只是一个远程的'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)
如果我只有在github
指向的origin
,git1.6.5的status
将是干净的。
它可能与早期的git提前警告,但无论如何,显式定义的git config branch.master.remote yourGitHubRepo.git
应该能够照顾,即使是早期版本的Git。
你是否小心使用git remote add NAME URL
来添加所有的远程(除了原始克隆附带的origin
)? 刚刚添加到gitconfiguration中时,我看到了这个bug。