前言

关于Git, 信任咱们最常用的便是pull和push. 但随着协作规划的提高, 遇到的问题也会越来越多. 本篇文章并不科普一些指令的具体用法, 更多的是分享在工作中遇到的Git场景问题以及踩过的坑

棘手? 那就别办咯

先来个开胃小菜. 一般公司都会有个dev分支用来布置测试版的功用. 也由于对错正式环境, 所以比较随意, 更新的也很频繁. 每次咱们运用dev分支之前都需求确保本地的dev分支是最新代码.

这些Git事端灾祸, 你经历过几个?

可怕, 我十分清楚pull一下必定都是抵触.

这些Git事端灾祸, 你经历过几个?

老实人或许还想着如何一个个去处理抵触.

这些Git事端灾祸, 你经历过几个?

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

这些Git事端灾祸, 你经历过几个?

Revert的圈套

业务布景

信任咱们对这个指令并不生疏. 当你想要回退某一条commit的时分, 能够这样做.

git revert xxx

现在咱们来看一个场景问题, 今日是你担任合代码. 你的搭档告诉你, feat/talk分支的使命需求上线, 所以你熟练地敲下兼并指令

这些Git事端灾祸, 你经历过几个?

刚方才履行完, 你的搭档就跑来和你说弄错了, 这个分支不应该被兼并的. 此时你捏紧了拳头, 十分想揍他. 可是你忍了. 你想到revert能够处理这个问题. 所以你找到了兼并的commit id化解危机.

这些Git事端灾祸, 你经历过几个?

轻轻松松~ 此时的你犹如杀敌的将军般意气风发. 而你的搭档又跑来和你说, 不好意思又搞错了. 这个使命确实是要上的. 此时你十分懊悔, 懊悔刚刚为什么没揍他. 可是这可怎么办呢? 所以你就故技重施.

这些Git事端灾祸, 你经历过几个?

十分奇特的是, 这次的merge, 却提示已经是最新代码了. 所以你查看文件改变、log日志, 都和刚刚revert完的如出一辙. 卧槽, 鬼打墙了?!

处理方案

问题其实就出在merge这个指令, 你了解错了. merge, 比照的是2个分支的commit. 什么意思呢. 咱们别离看看2个分支的commit有什么不一样

master:

这些Git事端灾祸, 你经历过几个?

feat/talk:

这些Git事端灾祸, 你经历过几个?

那么当你想在master分支merge feat/talk的时分, 是不是feat/talk有的commit在master都已经有了? 尽管你revert了, 可是也并没有影响他该有的commit还在啊. 所以你merge的时分他认为没有新的commit产生, 也没毛病.

cherry pick

能够独自cherry pick相应的commit id. 由于cherry pick是针对单个提交的操作, 它不会关心或受到该提交是否已被撤销的影响, 它只重视将指定提交的更改重新引进到当时分支.

这些Git事端灾祸, 你经历过几个?

revert你的revert

这句话听起来有点绕, 可是细心想想应该能了解, 简单说便是负负得正.

这些Git事端灾祸, 你经历过几个?

抵触多到爆破

假如你的团队协作规划在10个人以上, 则很有或许呈现十分复杂的抵触. 依据咱们的发版周期、使命持续周期等多个要素影响, 会有各种不同类型的抵触呈现. 今日我的粉丝群就有个同学问了这样的一个问题

“远端master是v19的版别, 而本地的master是v18的版别, 在一个月前, 从v18的master切出来使命分支开发功用, 我总共提交了50次代码, 现在要同步下master的代码, 发现抵触有300多个文件. 我要溃散了!”

莫慌! 处理300个文件的抵触确实不太实际. 首要咱们把他这个分支状况画出来

这些Git事端灾祸, 你经历过几个?

大概便是上面这个姿态, 远端和本地的1号和2号是一起的先人commit. 可是后面就自立山头了. 图中只画了4个不同的节点, 按这位同学的说法, 他提交了50个节点, 而远端不确定有多少个, 横竖抵触是300多个文件.

首要, 这50个commit咱们能够运用squash压缩成一个commit.

squash的作用便是将多个commit兼并成一个. 用法不解释了, 有点小麻烦, 百度都有.

那此时, 咱们的图就变成了下面这样

这些Git事端灾祸, 你经历过几个?

先不说你的新代码改动. 单单说你本地的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事端灾祸, 你经历过几个?

转载需注明出处且不得删减内容