侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 292 篇文章
  • 累计创建 132 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Git更新代码方式git fetch, git pull详解

孔子说JAVA
2022-09-03 / 0 评论 / 0 点赞 / 68 阅读 / 2,811 字 / 正在检测是否收录...

在我们使用git更新代码的时候用的是git fetch,git pull这两条指令。git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。而git pull 则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。

image-1662119501377

1、Git运行机制

git的运行机制: git分为本地仓库和远程仓库,一般情况下都是写完代码后 commit 到本地仓库(生成本地仓的commit ID,代表当前提交代码的版本号),然后push到远程仓库(记录这个版本号)。

在我们本地的git文件夹里面对应也存储了git本地仓库master分支的commit ID 和 跟踪的远程分支orign/master的commit ID(可以有多个远程仓库)。那什么是跟踪的远程分支呢,打开git文件夹可以看到如下文件:

  • .git/refs/head/[本地分支]
  • .git/refs/remotes/[正在跟踪的分支]

其中head就是本地分支,remotes是跟踪的远程分支,这个类型的分支在某种类型上是十分相似的,他们都是表示提交的SHA1校验和(就是commitID)。但是,不管他们是如何的相似,他们还是有一个重大的区别:

  • 更改远端跟踪分支只能用git fetch,或者是git push后作为副产品(side-effect)来改变。我们无法直接对远程跟踪分支操作,我们必须先切回本地分支然后创建一个新的commit提交。

image-1662119990384

假设我们本地仓库的 master 分支上 commit ID =1 ,orign/mastter中的commit ID =1 ;这时候远程仓库有人更新了github ogirn库中master分支上的代码,新的代码版本号commit ID =2 ,那么在github上 orign/master的commitID=2。

image-1662120086069

接下来我们看下不同方式如何更新代码。

2、git fetch更新代码

使用git fetch更新代码,本地的库中master的commitID不变,还是等于1。但是与git上面关联的那个orign/master的commit ID变成了2。这时候我们本地相当于存储了两个代码的版本号,我们还要通过merge去合并这两个不同的代码版本,如果这两个版本都修改了同一处的代码,这时候merge就会出现冲突,然后我们解决冲突之后就生成了一个新的代码版本。

  • 这时候本地的代码版本可能就变成了commit ID=3,即生成了一个新的代码版本。

image-1662120645940

相当于fetch的时候本地的master没有变化,但是与远程仓关联的那个版本号被更新了,我们接下来就是在本地合并这两个版本号的代码。

git fetch 命令:

# 这个命令将某个远程主机的更新全部取回本地
$ git fetch <远程主机名> 

如果只想取回特定分支的更新,可以指定分支名:

# 注意之间有空格
$ git fetch <远程主机名> <分支名> 

# 最常见的命令如取回origin 主机的master 分支
$ git fetch origin master

取回更新后,会返回一个FETCH_HEAD ,指的是某个branch在服务器上的最新状态,我们可以在本地通过它查看刚取回的更新信息:

$ git log -p FETCH_HEAD

image-1662121097427

可以看到返回的信息包括更新的文件名,更新的作者和时间,以及更新的代码(19行红色[删除]和绿色[新增]部分)。

我们可以通过这些信息来判断是否产生冲突,以确定是否将更新merge到当前分支。

3、git pull更新代码

使用git pull更新代码的话就比较简单暴力了,看下图。

image-1662120704411

使用git pull的时候会将本地的代码更新为远程仓库里面最新的代码版本。git pull 的过程可以理解为:

# 从远程主机的master分支拉取最新内容 
git fetch origin master 
# 将拉取下来的最新内容合并到当前所在的分支中
git merge FETCH_HEAD

即将远程主机的某个分支的更新取回,并与本地指定的分支合并,git pull 完整格式可表示为:

$ git pull <远程主机名> <远程分支名>:<本地分支名>

如果远程分支是与当前分支合并,则冒号后面的部分可以省略:

$ git pull origin next

4、总结

git pull看起来像git fetch+get merge,但是根据commit ID来看的话,他们实际的实现原理是不一样的。尽量不要用git pull,用git fetch和git merge代替它。

  • git pull的问题是它把过程的细节都隐藏了起来,以至于你不用去了解git中各种类型分支的区别和使用方法。当然,多数时候这是没问题的,但一旦代码有问题,你很难找到出错的地方。看起来git pull的用法会使你吃惊,简单看一下git的使用文档应该就能说服你。
  • 将下载(fetch)和合并(merge)放到一个命令里的另外一个弊端是,你的本地工作目录在未经确认的情况下就会被远程分支更新。当然,除非你关闭所有的安全选项,否则git pull在你本地工作目录还不至于造成不可挽回的损失,但很多时候我们宁愿做的慢一些,也不愿意返工重来。

附分支(branch)的基本操作:

git branch //查看本地所有分支 

git branch -r //查看远程所有分支

git branch -a //查看本地和远程的所有分支

git branch <branchname> //新建分支

git branch -d <branchname> //删除本地分支

git branch -d -r <branchname> //删除远程分支,删除后还需推送到服务器
git push origin:<branchname>  //删除后推送至服务器

git branch -m <oldbranch> <newbranch> //重命名本地分支
/**
*重命名远程分支:
*1、删除远程待修改分支
*2、push本地新分支到远程服务器
*/

//git中一些选项解释:

-d
--delete:删除

-D
--delete --force的快捷键

-f
--force:强制

-m
--move:移动或重命名

-M
--move --force的快捷键

-r
--remote:远程

-a
--all:所有

git commit、git push、git pull、 git fetch、git merge 的含义与区别

  • git commit:是将本地修改过的文件提交到本地库中;
  • git push:是将本地库中的最新信息发送给远程库;
  • git pull:是从远程获取最新版本到本地,并自动merge;
  • git fetch:是从远程获取最新版本到本地,不会自动merge;
  • git merge:是用于从指定的commit(s)合并到当前分支,用来合并两个分支;
  • git merge -b:指将 b 分支合并到当前分支
0

评论区