Git使用不当导致代码丢失的N种场景

简介: 背景git作为目前使用最广泛的分布式版本控制软件,集团内基本上所有开发同学都使用它来做代码管理。一个最典型的使用场景,是一个git仓库存在一个master主干分支,多个需求基于master拉自己的开发分支,然后在发布日时,新建一个release分支,然后原先并行的几个开发分支merge到release分支上,最后基于该分支发布上线,上线后release再merge到master主干上,一次发布完成

背景

git作为目前使用最广泛的分布式版本控制软件,集团内基本上所有开发同学都使用它来做代码管理。

一个最典型的使用场景,是一个git仓库存在一个master主干分支,多个需求基于master拉自己的开发分支,然后在发布日时,新建一个release分支,然后原先并行的几个开发分支merge到release分支上,最后基于该分支发布上线,上线后release再merge到master主干上,一次发布完成。

但由于每位开发同学对git的掌握程度不一,可能对git使用不当,导致某次提交丢失了部分曾经已经在git仓库的代码,最后该分支发布上线后造成故障。并且这种丢代码情况在代码改动量本身就很多的时候,往往比较隐秘,并且如果丢失的代码不在本次变更的范围内,测试回归时可能也就不会涉及到,结果就是只有在线上真正发生故障时才意识到问题。

所以这里梳理了一下有哪些不当使用git可能会导致代码丢失的场景,防止踩坑。如果有遗漏的其它场景,也请留言补充。

场景梳理

1)强制Push

触发场景

在多人并行开发同一个分支时,某人写完代码,git push,如果此时该分支已经也被别人改过且push过了,则会提示这个信息:

此时不熟悉git的同学,可能会通过加 -f 参数,强制push:

git push -f origin branchA

或者在IDEA里面,选择了Force Push:

这样之前别人已经push的代码,就被丢掉了(因为将会以你本地非最新的代码为准)。

正确操作

push代码遇到本地不是最新时,不要强制push!务必先git pull拉最新代码,如果遇到冲突则解决冲突,解决完再git push。

2)Merge时错误处理冲突

触发场景

在自己的分支上开发,然后需要将其它分支(例如master)的代码merge过来时,遇到了代码冲突,此时处理完冲突后,push代码,如果没有发生冲突的其它分支文件,没有同时也勾选push的话,则代码也会丢失。

例如下面的例子:

  • 在dev分支上修改了Tester.java文件和其它内容,merge master提示其中Tester.java有冲突;

  • 处理完Tester.java的冲突后,在IDEA里面准备push代码,此时展现了有修改的文件列表(如下图)。此时列表内不仅有自己在dev分支里面修改的代码,还有被合并过来的分支(master)修改的文件(图中ClassA和ClassB)。

  • 此时正确操作,是必须要把ClassA和ClassB 这些master上修改的文件内容,也勾选上。 如果未勾选,而只勾了自己在dev上修改的文件,再去push,则此时master上这些修改的代码会丢失。

正确操作

merge后遇到冲突,解决完冲突后,不要部分提交!push时务必把所有修改文件都勾选,再push。

这个对于IDEA这种图形化界面容易犯错。对于命令行,其实merge冲突后,未冲突的文件,是默认已经放入暂存区了,所以git push时这些未冲突文件就会一起被正确push上去。

3)错误使用Merge

触发场景

有的时候可能遇到这种情况:自己的开发分支,需要将其他开发分支上的改动merge过来,但是只需要其中部分功能,此时如果使用git merge的话,就可能会存在问题。

例如下面这个例子:

主干Master上有两个文件:fileA和fileB。其中fileA的内容是AAA,fileB的内容是BBB。最新的CommitId是M1;

  1. 张三基于Master,拉了一个分支:Dev1,其最新CommitId是G1,其中fileA和fileB的内容没有变更;
  2. 李四也基于Master,拉了一个分支:Dev2,其最新CommitId是P1,其中fileA和fileB的内容也没有变更;
  3. Dev1分支,做了一次commit,ID是G2,其中把fileA和fileB的内容都做了变更(fileA变成AAA1,fileB变成BBB1);
  4. Dev2分支,希望能将Dev1的代码Merge过来,但只想要fileB的改动,而暂时不需要fileA的改动,于是他执行git merge Dev1,然后rollback了其中fileA的变化,提交,commitId为P2;
  5. Dev1分支发布,代码被合并到了Master,此时Master的CommitId为M2,并且fileA和fileB内容都以Dev1的G2为准(即fileA是AAA1,fileB是BBB1);
  6. Dev2继续开发,然后等Dev2自己也准备要发布了,于是他执行git merge master合并最新主干代码(CommitId是P3)。此时他以为fileA的内容会被改成AAA1,因为Master上就是AAA1,但其实因为之前merge Dev1时,fileA被自己人工改过了,所以会以自己版本为准,即实际内容还是AAA。此时Dev2的代码已经有问题了;
  7. 最后Dev2分支发布,代码被合并到了Master,其CommitID是M2,其中fileA的内容也在主干里面被丢失了,导致故障。

正确操作

出问题的点在Dev2的Commit P2。对于这种希望将其它分支上的部分改动(例如某几个commit)移动到自己分支上的情况,强烈建议是不要使用git merge,而是使用cherry-pick将这几个commit合并过来

预防策略

目前能做的更多还是在机制上做兜底。典型的就是在发布前,发布分支和master做diff。在这个环节里,不再关心需求代码写的怎么样(这个是之前CR时做的),而是只关心Diff出来的内容,是否是我们要的,特别是diff出来被删除/修改的逻辑,确认是否是发布的业务需求逻辑。如果不是,或者没人知道这部分逻辑是谁改的为啥改,那就有问题,可能是之前Merge时丢代码了。

相关文章
|
3月前
|
IDE 网络安全 开发工具
【Azure App Service】Local Git App Service的仓库代码遇见卡住不Clone代码的问题
【Azure App Service】Local Git App Service的仓库代码遇见卡住不Clone代码的问题
【Azure App Service】Local Git App Service的仓库代码遇见卡住不Clone代码的问题
|
3月前
|
开发工具 数据安全/隐私保护 git
记录一次使用git工具拉取coding上代码密码账号错误的经历
这篇文章记录了作者在使用Git工具从Coding平台克隆项目时遇到的账号密码错误问题,并分享了通过清除电脑凭证中错误记录的账号密码来解决这个问题的方法。
记录一次使用git工具拉取coding上代码密码账号错误的经历
|
3月前
|
开发工具 git Python
通过Python脚本git pull 自动重试拉取代码
通过Python脚本git pull 自动重试拉取代码
179 5
|
27天前
|
开发工具 git
git如何修改提交代码时的名字和邮箱?
git如何修改提交代码时的名字和邮箱?
40 4
|
1月前
|
Java Linux 开发工具
IDEA中git提交前如何关闭code analysis以及开启格式化代码
【10月更文挑战第12天】本文介绍了在 IntelliJ IDEA 中关闭代码分析和开启代码格式化的步骤。关闭代码分析可通过取消默认启用检查或针对特定规则进行调整实现,同时可通过设置 VCS 静默模式在提交时跳过检查。开启代码格式化则需在 `Settings` 中配置 `Code Style` 规则,并通过创建 Git 钩子实现提交前自动格式化。
|
2月前
|
Shell 网络安全 开发工具
git与gitee结合使用,提交代码,文件到远程仓库
本文介绍了如何将Git与Gitee结合使用来提交代码文件到远程仓库。内容涵盖了Git的安装和环境变量配置、SSH公钥的生成和配置、在Gitee上创建仓库、设置Git的全局用户信息、初始化本地仓库、添加远程仓库地址、提交文件和推送到远程仓库的步骤。此外,还提供了如何克隆远程仓库到本地的命令。
git与gitee结合使用,提交代码,文件到远程仓库
|
26天前
|
JavaScript 前端开发 开发工具
一身反骨的我,用--no-verify绕开了git代码提交限制!
【10月更文挑战第7天】一身反骨的我,用--no-verify绕开了git代码提交限制!
80 0
|
3月前
|
Shell 开发工具 git
使用 Shell 代码简化 Git 步骤
【8月更文挑战第23天】本文介绍通过Shell脚本简化Git操作的方法:1) 使用`gitc "提交信息"`可一键完成代码提交与推送至远程仓库;2) 执行`gitpull`即可从远程仓库拉取最新代码并合并到当前分支;3) 输入`gitnewbranch 分支名称`快速创建并切换到新分支。将这些自定义函数加入`.bashrc`或`.zshrc`等配置文件后,即可随时调用简化版Git命令。
|
3月前
|
安全 开发工具 git
coding上创建项目、创建代码仓库、将IDEA中的代码提交到coding上的代码仓库、Git的下载、IDEA上配置git
这篇文章是关于如何在IDEA中配置Git、在Coding.net上创建项目和代码仓库,并将IDEA中的代码提交到远程代码仓库的详细教程,涵盖了Git安装、IDEA配置、项目创建、代码提交等步骤。
coding上创建项目、创建代码仓库、将IDEA中的代码提交到coding上的代码仓库、Git的下载、IDEA上配置git
|
3月前
|
前端开发 JavaScript PHP
【Azure 应用服务】App Service 在使用GIt本地部署,上传代码的路径为/home/site/repository,而不是站点的根目录/home/site/wwwroot。 这个是因为什么?
【Azure 应用服务】App Service 在使用GIt本地部署,上传代码的路径为/home/site/repository,而不是站点的根目录/home/site/wwwroot。 这个是因为什么?