这些Git事故灾难, 你经历过几个?
前言
关于Git, 相信大家最常用的就是pull和push. 但随着协作规模的提升, 遇到的问题也会越来越多. 本篇文章并不科普一些命令的详细用法, 更多的是分享在工作中遇到的Git场景问题以及踩过的坑
难办? 那就别办咯
先来个开胃小菜. 一般公司都会有个dev分支用来部署测试版的功能. 也因为是非正式环境, 所以比较随意, 更新的也很频繁. 每次我们使用dev分支之前都需要保证本地的dev分支是最新代码.

可怕, 我非常清楚pull一下一定都是冲突.

老实人可能还想着如何一个个去解决冲突.

但是为什么要解决呢? 我们又没在dev分支上开发, 我们不过是想获得最新版的分支内容, 所以我们完全可以直接把dev删了, 然后再切个dev就好了. 当一个分支本地不存在的时候, 他就会从远端切.

Revert的陷阱
业务背景
相信大家对这个命令并不陌生. 当你想要回退某一条commit的时候, 可以这样做.
git revert xxx
现在我们来看一个场景问题, 今天是你负责合代码. 你的同事告诉你, feat/talk分支的任务需要上线, 于是你熟练地敲下合并命令

刚刚才执行完, 你的同事就跑来和你说弄错了, 这个分支不应该被合并的. 此时你捏紧了拳头, 非常想揍他. 但是你忍了. 你想到revert可以解决这个问题. 于是你找到了合并的commit id化解危机.

轻轻松松~ 此刻的你犹如杀敌的将军般英姿飒爽. 而你的同事又跑来和你说, 不好意思又搞错了. 这个任务确实是要上的. 此刻你非常后悔, 后悔刚刚为什么没揍他. 但是这可怎么办呢? 于是你就故技重施.

非常神奇的是, 这次的merge, 却提示已经是最新代码了. 于是你查看文件变更、log日志, 都和刚刚revert完的一模一样. 卧槽, 鬼打墙了?!
解决方案
问题其实就出在merge这个命令, 你理解错了. merge, 对比的是2个分支的commit. 什么意思呢. 我们分别看看2个分支的commit有什么不一样
master:

feat/talk:

那么当你想在master分支merge feat/talk的时候, 是不是feat/talk有的commit在master都已经有了? 虽然你revert了, 但是也并没有影响他该有的commit还在啊. 所以你merge的时候他认为没有新的commit产生, 也没毛病.
cherry pick
可以单独cherry pick相应的commit id. 因为cherry pick是针对单个提交的操作, 它不会关心或受到该提交是否已被撤销的影响, 它只关注将指定提交的更改重新引入到当前分支.

revert你的revert
这句话听起来有点绕, 但是仔细想想应该能理解, 简单说就是负负得正.

冲突多到爆炸
如果你的团队协作规模在10个人以上, 则很有可能出现非常复杂的冲突. 根据大家的发版周期、任务持续周期等多个因素影响, 会有各种不同类型的冲突出现. 今天我的粉丝群就有个同学问了这样的一个问题
"远端master是v19的版本, 而本地的master是v18的版本, 在一个月前, 从v18的master切出来任务分支开发功能, 我一共提交了50次代码, 现在要同步下master的代码, 发现冲突有300多个文件. 我要崩溃了!"
莫慌! 解决300个文件的冲突确实不太现实. 首先我们把他这个分支情况画出来

大概就是上面这个样子, 远端和本地的1号和2号是共同的祖先commit. 但是后面就自立山头了. 图中只画了4个不同的节点, 按这位同学的说法, 他提交了50个节点, 而远端不确定有多少个, 反正冲突是300多个文件.
首先, 这50个commit我们可以使用squash压缩成一个commit.
squash的作用就是将多个commit合并成一个. 用法不解释了, 有点小麻烦, 百度都有.
那此刻, 我们的图就变成了下面这样

先不说你的新代码改动. 单单说你本地的v18master和origin的v19master绝对都是有冲突的. 参考本文的开头案例, 不需要去合并, 只需要把v18删了就行了. 那么你的本地master也就保持了最新. 最后, 直接cherry 5就可以了.
这里再提另一个思路, 其实这个场景最核心的就是将50个commit转化为1个commit. 除了squash还有个办法, 就是reset. 可以reset到第一次提交的内容, 再次commit, 也可以实现这个效果.
stash的阳奉阴违
我们经常会在做完一些改动后, 可能由于各种原因, 需要暂存下代码. 这里就会用到stash. 你可能以为你的代码修改都会被保存下来. 但并不是这样的, stash只会保存modify的文件, 不会保存untracked文件. 说人话就是新建的文件是不会被暂存的. 而实际上, 我们几乎不可能出现只想保存文件变更, 不想保存新建的文件. 所以一定要加上参数--include-untracked才可以.
另外, 取出stash的内容, 很多人喜欢用stash pop. 我更推荐你用stash apply. 区别是pop在取出stash的内容后会直接删除掉暂存的stash. 这时候一旦你的更改又出现问题, 你就回不去了. 而apply则随时可以放弃所有变更从头再来.
核弹洗地
及时提交commit, 避免了代码丢失, 也保证了代码片段的独立性. 我们有时候会在编辑代码后发现改了不少东西, 但是这些都是不需要了的, 想要全部放弃掉. 比较常见的情况是给同事写个demo临时演示下, 搞完就不需要了. 可以使用以下命令.
git checkout . && git clean -fd
前半部分会恢复你的代码变更, 后半部分则会删除新建的文件. 但是这么长的命令谁记得住啊. 所以我建议使用git的别名设置
别名的配置用法网上很多, 搜索 git alias
ddd = !git checkout . && git clean -fd
为什么我设置的是3个d呢? 这里想和大家说个趣事儿. 几年前我的名别设置如下
ad = add .
d = !git checkout . && git clean -fd
因为discard这个单词, 所以我把这个命令设置了为单字母d. 和往常一样, 写完代码我的肌肉记忆就敲出了如下操作
git ad
git commit
但是当时可能键盘的a键有点不灵敏, 就敲出了git d并且回车了. 当场心态崩了. 大家可能说现在的vsc就算撤销了代码, cmd+z还是会回来部分代码的. 但是几年前并没有. 而且当时我在开发的任务非常复杂, 我写了一整天, 就这样没了. 最后找回来了吗? 没有, 我重新写了一遍. 之后我就改为了3个d, 确保绝对不可能误触.
如果是现在发生这种情况, 也许reflog还能救一下, 也只是也许, 因为防范于未然一定优于亡羊补牢.
总结
以上都是笔者在多年的实际工作中出了事故踩了坑而得出的总结, 不知道你是否也有类似的git事故经验呢? 欢迎在评论区分享.
我是前夕, 专注于前端和成长. 公众号: 前夕小课堂

转载需注明出处且不得删减内容
这些Git事故灾难, 你经历过几个?的更多相关文章
- git 大型灾难现场
由于某种原因,需要重建git仓库.因此删了所有分支,重建git仓库. 删除整个过程 删除所有分支(除master外) git branch -d {branch_name} # 删除本地分支 git ...
- Git 无法拉取,Unlink of file '.git/objects/pack/pack-***.pack' failed. Should I try again? (y/n)
现象 Git 无法拉取,提示: Unlink of file '.git/objects/pack/pack-***.pack' failed. Should I try again? (y/n) 原 ...
- Git 快速控制
Git 快速控制 聊聊学习 Git 那些事 现在回想起来,其实接触 Git 的时候是在大一的时候表哥带入门的.当时因为需要做一个项目,所以他教如何使用 Git 将写好的代码推送到 GitHub 上,然 ...
- 『现学现忘』Git基础 — 18、Git对象的总结
目录 1.Git操作最基本的流程 2.工作目录中文件的状态 3.Git效率说明 提示:前面三篇文章已经分别的对blob对象.tree对象.commit对象进行了详细的说明,这篇文章我们总结一下,Git ...
- $2015 武汉森果公司web后端开发实习日记----书写是为了更好的思考
找暑期实习,3月份分别投了百度和腾讯的实习简历,都止步于笔试,总结的主要原因有两点:基础知识不扎实,缺乏项目经验.后来到拉勾网等网站上寻找实习,看了很多家,都还是处于观望状态.后来参加了武汉实习吧在大 ...
- 记一次git amend事故处理方案
一.问题回顾 问题是git commit --amend 引起的. 一条commit已经push到远端develop了,但是后来又在这条commit上进行了amend操作,导致这条commit的哈希码 ...
- Git x SVN rebase事故
Git x SVN rebase事故 @author ixenos 2019-01-09 14:21:21 前言: 昨天在Git x SVN 中进行git svn dcommit的时候,提示需要再进行 ...
- git 中文乱码-一次被坑经历
git log和gitcommit中文出现乱码,花了大半天的时间试了网上的各种方法,还是搞不定. 只好放大招. 卸载软件后重装,还是不行.然后git config --list 发现一些奇怪的配置信息 ...
- 「生产事故」MongoDB复合索引引发的灾难
前情提要 11月末我司商品服务的MongoDB主库曾出现过严重抖动.频繁锁库等情况. 由于诸多业务存在插入MongoDB.然后立即查询等逻辑,因此项目并未开启读写分离. 最终定位问题是由于:服务器自身 ...
- 记一次git merge 事故
最近发生在自己身上的一件矬事儿,一不小心把matser上别人的代码给冲掉了,事后追溯了下原因. 1.准备三个分支,分别从master拉取 realease/v1.0分支 和 realease/bugf ...
随机推荐
- 工具 --- IL指令集解释
引言 汇总一下所有的 .NET IL 指令,以及它们的名称.操作码值.堆栈转换行为和描述. 作为反编译IL代码时的查询字典. IL 指令集列表 以下内容来自微软官方文档,通过百度翻译API翻译为中文. ...
- Obsidian 设置快捷键 Ctrl+Shift+J 打开OB(未启动则启动,启动未激活则激活,已激活则最小化)- autoHotKey
Obsidian 设置快捷键 Ctrl+Shift+J 打开OB(未启动则启动,启动未激活则激活,已激活则最小化)- autoHotKey 需求 将Obsidian作为主笔记软件使用,设置个快捷键,配 ...
- 选择单词后 按 ctrl + space 单词发音
需求: 在ide或其他地方,经常有单词发音不是很确定,但并不要很详细 就听个单词发音. 确定快捷键: 左手单手操作,我键盘上貌似就 左边的ctrl和空格键 还没有设定 翻译软件: 使用 pc端的 欧路 ...
- Pandas导出美化技巧,让你的Excel更出众
pandas的DataFrame可以通过设置参数使得在jupyter notebook中显示的更加美观,但是,将DataFrame的数据导出excel时,却只能以默认最朴素的方式将数据写入excel. ...
- kubectl create 与 kubectl apply的区别
kubectl apply和kubectl create都是Kubernetes(k8s)中用于创建或更新资源的命令,但它们在使用方式.功能和灵活性上存在一些区别. 声明式与命令式: kubectl ...
- day09-Java数组
Java数组 9.稀疏数组 什么是稀疏数组? 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组. 稀疏数组的处理方式是: 记录数组一共有几行几列,有多少个不同的值 把具有 ...
- 3DCAT+东风日产:共建线上个性化订车实时云渲染方案
近年来,随着5G网络和云计算技术的不断发展,交互式3D实时云看车正在成为一种新的看车方式. 与传统的到4S店实地考察不同,消费者可以足不出户,通过网络与终端设备即可实现全方位展示.自选汽车配色.模拟效 ...
- 三维模型3DTile格式轻量化在数据存储的重要性分析
三维模型3DTile格式轻量化在数据存储的重要性分析 三维模型3DTile格式轻量化在数据存储中占有重要地位.随着科技的不断发展,尤其是空间信息科技的进步,人们对于三维地理空间数据的需求日益增长.然而 ...
- Python实现简易版Netcat
Netcat Netcat是一种网络工具,也称为"nc",可用于在计算机网络之间进行TCP/IP或UDP连接.它可以用于连接到其他计算机上的端口,发送和接收数据,扫描端口以及创建服 ...
- 记录--记录用前端代替后端生成zip的过程,速度快了 57 倍!!!
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 业务场景: 产品有个功能是设置主题.类似手机自动切换壁纸,以及其他功能颜色,icon,字体等. 管理员需要在后端管理系统多次下载不同主题, ...