git fetch和git pull的区别
git pull会将本地库更新至远程库的最新状态,git pull 是git fetch与git merge的组合。所以虽然从结果上来看,git pull = git fetch + git merge,但是从文件中保存的commit id来看,实现上不是这样实现的
为了更好的理解,画了个图:
每一个本地库下都有一个.git的隐藏文件夹,文件夹中的文件保存着跟这个本地库相关的信息:
首先来看下其中的config文件:
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
[remote "origin"]
url = git@github.com:tobeyabc/fetch.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
从这个文件中我们可以了解到:
本地库的当前分支为master,其关联的远程库名称为origin
远程库origin所在的位置为(URL):git@github.com:tobeyabc/fetch.git
然后可以查看.git文件夹下的HEAD文件:
ref: refs/heads/master
其指向.git\refs\heads\master文件,这个文件中保存的是本地库中最新的commit id:
ce71505b3626a3648b2c32ea2081d65049cad300
.git\refs文件夹很有意思,面分为3个文件夹:
heads文件夹前面说过了。remotes文件夹中的每一个文件夹代表一个远程库名称(git remote),其中的每个文件关联远程库的一个分支,其中保存该分支的最新commit id。
git fetch之后,git fetch只会将本地库所关联的远程库的commit id更新至最新,也就是.git\refs\remotes\origin\master里面的commit id,而.git\refs\heads\master里面的commit id是不会改变的。HEAD没有变化很容易理解,因为本地库并没有变化。
git fetch和git merge的应用
假如想比较,本地分支与线上分支的差别,就可以先
git fetch
这样就可以用git diff origin/xxx
(这里 origin 是对远程仓库的命名),进行比较了。比如拉取某个分支之前,想看看区别,可以
git fetch origin develop
然后通过
git diff HEAD FETCH_HEAD
查看改动了哪些文件。如果想查看某个文件具体变动了什么可以用如下命令:
git diff HEAD FETCH_HEAD sql_version/develop/1/student.sql
如果一切都正常了,可以合并:
git merge origin develop