'git pull origin mybranch'离开本地mybranch N提前提交。 Why?
我只是观察到一些关于git pull
奇怪事情,我不明白。
星期五,我在当地的一家分店工作。 我们称它为mybranch
。 在离开办公室之前,我把它推到了原点(这是我的github回购): git push origin mybranch
。
昨天在家里,我pull
mybranch拖到我的笔记本电脑上,做了一些更多的编码,然后把我的修改推回给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
显然,我的本地回购是缺少一些参考对象,但怎么可能呢? 我的意思是,拉已经做了一个抓取,并且除了那个分支之外我没有做任何工作,所以git fetch origin
和git fetch origin mybranch
应该有相同的结果?
我应该总是使用git pull origin
而不是git pull origin branchname
?
我很困惑。
在合并明确提取的头部之前(或者如果远程分支没有配置为合并), git pull
在合并之前使用适当的参数调用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
了更多比起我,我会在大多数情况下依赖branch.<branch>.remote
来完成一个没有参数的简单的git pull
branch.<branch>.remote
和branch.<branch>.merge
为'做正确的事情'。
什么是git remote -v show
返回来源?
如果origin指向github,那么状态应该是最新的,而不是任何远程repo。 至少,使用Git1.6.5进行快速测试。
无论如何,要避免这种情况,请明确定义主分支的远程回购:
$ 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存储库中的“远程主分支”。
在这种情况下,您的本地主人似乎不再是远在主人的“前面”。
我可以用git1.6.5来测试这个:
首先我创建一个workrepo:
PS D:gittests> cd pullahead
PS D:gittestspullahead> git init workrepo
Initialized empty Git repository in D:/git/tests/pullahead/workrepo/.git/
PS D:gittestspullahead> cd workrepo
PS D:gittestspullaheadworkrepo> echo firstContent > afile.txt
PS D:gittestspullaheadworkrepo> git add -A
PS D:gittestspullaheadworkrepo> git commit -m "first commit"
我通过创建一个裸回购(可从任何地方接收推送的回购)来模拟GitHub回购。
PS D:gittestspullaheadworkrepo> cd ..
PS D:gittestspullahead> git clone --bare workrepo github
我在我的工作回购中添加了一个修改,我推送到github回购(作为远程添加)
PS D:gittestspullahead> cd workrepo
PS D:gittestspullaheadworkrepo> echo aModif >> afile.txt
PS D:gittestspullaheadworkrepo> git ci -a -m "a modif to send to github"
PS D:gittestspullaheadworkrepo> git remote add github d:/git/tests/pullahead/github
PS D:gittestspullaheadworkrepo> git push github
我创建了一个家庭回购,克隆了GitHub,我在其中进行了一些修改,推送到GitHub:
PS D:gittestspullaheadworkrepo> cd ..
PS D:gittestspullahead> git clone github homerepo
PS D:gittestspullahead> cd homerepo
PS D:gittestspullaheadhomerepo> type afile.txt
firstContent
aModif
PS D:gittestspullaheadhomerepo> echo aHomeModif1 >> afile.txt
PS D:gittestspullaheadhomerepo> git ci -a -m "a first home modif"
PS D:gittestspullaheadhomerepo> echo aHomeModif2 >> afile.txt
PS D:gittestspullaheadhomerepo> git ci -a -m "a second home modif"
PS D:gittestspullaheadhomerepo> git push github
然后我克隆workrepo第一个实验
PS D:gittestspullaheadworkrepo4> cd ..
PS D:gittestspullahead> git clone workrepo workrepo2
Initialized empty Git repository in D:/git/tests/pullahead/workrepo2/.git/
PS D:gittestspullahead> cd workrepo2
PS D:gittestspullaheadworkrepo2> git remote add github d:/git/tests/pullahead/github
PS D:gittestspullaheadworkrepo2> 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:gittestspullaheadworkrepo5> 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:gittestspullaheadworkrepo2> 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的起源的repo中重复序列(或者根本没有起源,只是一个远程的'github'定义),状态就是干净的:
PS D:gittestspullaheadworkrepo2> cd ..
PS D:gittestspullahead> git clone workrepo workrepo4
PS D:gittestspullahead> cd workrepo4
PS D:gittestspullaheadworkrepo4> git remote rm origin
PS D:gittestspullaheadworkrepo4> git remote add github d:/git/tests/pullahead/github
PS D:gittestspullaheadworkrepo4> 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:gittestspullaheadworkrepo4> 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
文件除外)? 当他们刚被添加到git配置中时,我看到了这个bug。
上一篇: 'git pull origin mybranch' leaves local mybranch N commits ahead of origin. Why?
下一篇: only repo's 'git status' saying the branch is ahead of origin/master. Why?