git fetch 会抓取或者克隆远端推送的新内容,它把数据下载到本地仓库里,但是不会自动合并或者修改你当前分支的内容。抓取以后我们可以查看 、比较远端分支的代码,或者从远端分支的内容创建一个新的分支。
1. git diff origin/master
2. git checkout origin/master
3. git checkout -b review_branch origin/master 或者 git switch -c review_branch origin/master
git pull 只有设置了跟踪远程分支才有效,git clone 默认设置本地 master 分支跟踪远程仓库的 master 分支,先执行 git fetch,再执行 git merge 或者 git rebase 是相同的效果。怎么查看本地分支和远程分支的跟踪关系呢? 输入 git branch -vv 看看:
wangbo@wangbo-VirtualBox:~/test/learn-git$ git branch -vv
* feature_print 07f8e9a [origin/feature_print] add info
master 40b2935 [origin/master] add blank line
所以当我们在 feature_print 分支的时候,执行 git pull 会去拉取 origin/feature_print 的分支内容,然后两者进行合并,在 master 的时候会拉取 origin/master 来合并。如果你不想着合并代码,就先执行 git fetch origin 更新后,看看上面的提交信息和文件内容,确定后自行合并。
git push 的时候也遵循这个远程跟踪分支的设定,所以 push 的时候往往没有写远端的分支名称,可以通过命令手动设置跟踪的分支,push 的时候增加 -u 参数也是 --set-upstream 的意思。
git branch --set-upstream 本地分支名 origin/远程分支名
执行 git pull --help 可以看到文档解释第二部是操作 git merge FETCH_HEAD,这个 FETCH_HEAD 是什么呢? 它是 .git 文件夹下的一个文件,看看它的内容:
wangbo@wangbo-VirtualBox:~/test/learn-git$ cat .git/FETCH_HEAD
07f8e9a6adc9dc61feac4cb96e7e9f427cebeba3 branch 'feature_print' of github.com:developdeveloper/git-demo
40b293536dddd0fd2354a9dbfe11bb78ae44a8c9 not-for-merge branch 'master' of github.com:developdeveloper/git-demo
切换到本地的 master 分支,再做一次 git fetch origin,再次查看这个文件的内容:
wangbo@wangbo-VirtualBox:~/test/learn-git$ git switch master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
wangbo@wangbo-VirtualBox:~/test/learn-git$ git fetch origin
wangbo@wangbo-VirtualBox:~/test/learn-git$ cat .git/FETCH_HEAD
40b293536dddd0fd2354a9dbfe11bb78ae44a8c9 branch 'master' of github.com:developdeveloper/git-demo
07f8e9a6adc9dc61feac4cb96e7e9f427cebeba3 not-for-merge branch 'feature_print' of github.com:developdeveloper/git-demo
看来 FETCH_HEAD 的意思是最近 fetch 的那个提交点,它是一个引用。
希望你大概理解了 pull 和 push 的作用和原理了。