git pull 会导致本地为提交代码被覆盖吗?为啥我从来没出现过,啥情况下才会被覆盖呢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了git pull 会导致本地为提交代码被覆盖吗?为啥我从来没出现过,啥情况下才会被覆盖呢?相关的知识,希望对你有一定的参考价值。

我 pull的时候冲突都会提示冲突 然后 pull失败,pull 不是会merge吗,为什么会覆盖

前言

在我们使用git的时候用的更新代码是git fetch,git pull这两条指令。但是有没有小伙伴去思考过这两者的区别呢?有经验的人总是说最好用git fetch+git merge,不建议用git pull。也有人说git pull=git fetch+git merge,真的是这样吗?为什么呢?既然如此为什么git还要提供这两种方式呢?git深入学习

1. 相同点

首先在作用上他们的功能是大致相同的,都是起到了更新代码的作用。

2. 不同点

先补充一些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提交。

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

1. git fetch

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

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

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

2. git pull

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

使用git pull的会将本地的代码更新至远程仓库里面最新的代码版本

3. 总结

由此可见,git pull看起来像git fetch+get merge,但是根据commit ID来看的话,他们实际的实现原理是不一样的。

这里借用之前文献看到的一句话:

不要用git pull,用git fetch和git merge代替它。

git pull的问题是它把过程的细节都隐藏了起来,以至于你不用去了解git中各种类型分支的区别和使用方法。当然,多数时候这是没问题的,但一旦代码有问题,你很难找到出错的地方。看起来git pull的用法会使你吃惊,简单看一下git的使用文档应该就能说服你。

将下载(fetch)和合并(merge)放到一个命令里的另外一个弊端是,你的本地工作目录在未经确认的情况下就会被远程分支更新。当然,除非你关闭所有的安全选项,否则git pull在你本地工作目录还不至于造成不可挽回的损失,但很多时候我们宁愿做的慢一些,也不愿意返工重来。

结语:

码字不易看到最后了,那就点个关注呗,只收藏不点关注的都是在耍流氓!有了您的支持,我们会做得更好!

关注并私信我“架构”,免费送一些Java架构资料,先到先得!
参考技术A 如果你拉去的代码所包含的commit中, 有对你当前变更的文件进行的修改, 他就会报这个错误。如果你本地从的更高没有提交,他是不会自动尝试merge的。(merge只能合并已经提交的修改)

git pull会把本地未提交修改覆盖吗?

git pull会把本地未提交修改覆盖。

处理的方式非常简单,主要是使用git stash命令进行处理,分成以下几个步骤进行处理。

1、先将本地修改存储起来

$ git stash

这样本地的所有修改就都被暂时存储起来 。是用git stash list可以看到保存的信息:

git stash暂存修改

其中stash@0就是刚才保存的标记。

2、pull内容

暂存了本地修改之后,就可以pull了。

$ git pull

3、还原暂存的内容

$ git stash pop stash@0

系统提示如下类似的信息:

Auto-merging c/environ.c

CONFLICT (content): Merge conflict in c/environ.c

意思就是系统自动合并修改的内容,但是其中有冲突,需要解决其中的冲突。

4、解决文件中冲突的的部分

打开冲突的文件,会看到类似如下的内容:

git冲突内容

其中Updated upstream 和=====之间的内容就是pull下来的内容,====和stashed changes之间的内容就是本地修改的内容。碰到这种情况,git也不知道哪行内容是需要的,所以要自行确定需要的内容。

解决完成之后,就可以正常的提交了。

参考技术A 分两种情况:1无冲突,2有冲突
无冲突时,本地未提交修改不会被覆盖,能够执行pull。
有冲突时,提示“Your local changes to the following files would be overwritten by merge”,本次pull执行失败,并且不会拉取远程代码,不用担心。
参考技术B

    没有 add 的文件,不会被覆盖。add 了文件没有 commit,不能 pull。commit 了之后 pull 有冲突,会自行解决或者提示需要编辑。只要 commit 过,都可以用 git reflog 找回。

    git库版本与本地库版本冲突:个人定义为就是git库版本与本地库版本不匹配,详细地说就是我们从git库clone克隆下来的版本,经过修改后提交并合并成新版本,但是后来又将git库的该版本撤销了,而本地没有撤销该版本,此时就是本地库拥有此版本而git库中没有此版本。这样在使用git pull或git pull origin master可能会出现:“Your local changes to the following files would be overwritten by merge”或"PULL  不可用,因为您尚有未合并的文件“或"自动合并失败,修正冲突后提交修正后的结果"“Your local changes to the following files would be overwritten by merge”这样的错误,意思就是你的本地修改以下文件将被覆盖合并。

以上是关于git pull 会导致本地为提交代码被覆盖吗?为啥我从来没出现过,啥情况下才会被覆盖呢?的主要内容,如果未能解决你的问题,请参考以下文章

git pull会把本地未提交修改覆盖吗?

idea处理pull冲突

SVN更新代码的时候会覆盖本地文件吗?

git pull 之后本地代码被覆盖 解决方案

git学习 idea git pull 解决冲突

关于代码覆盖 or 冲突