同事和组长的一番对话引起了笔者对 git 的思考

先介绍一下我司小工坊式的 git 提交流程,本地打包,删除 dist 文件,重建 dist 文件,git add .git commit -m 'XX'git push origin 分支名

和传统公司的 git 提交不同,我司打包是本地打包,而且是把 dist 文件直接上传到仓库

事故现象

同事把代码推上去后,浏览器访问的还是原来的 js 和 css。

同事说:组长,需要你把 dist 删掉,重新再从仓库里拉一下最新的

组长:git 提交后不就把原来的 dist 替换了吗,你让我删 dist 有什么意义

扯皮了一会儿,组长还是删了然后重新拉,没想到好了

组长说:你的 dist 现在是最新的,所以现在就好了

同事具体说了什么笔者忘记了,大致上在辩护 git 提交不会把原来的 dist 文件删除问题,不过他没说服组长,组长也没说服他,反正已经安全上线而不了了之。

我正好在旁边听到了,要是两年前我也许会一直提出问题参与辩论,申援同事。但笔者没动,不是怕 PUA,而是表达能力太差,即使是对的,也说不好。其根本原因是笔者对这块知识了解的不深刻,所以不敢说大话

理论知识

按照理论知识,你 push 整个 dist 文件,即使远程仓库中有 dist,也不会把整个 dist 文件夹替换,只会替换其中相同的数据,而因为打了 hash 值,所以 css 和 js 都是不同的,所以一直这样做,dist 中的文件会越来越多,而因为 index.html 文件只有一个,所以不会出现替换了还引用之前文件的问题,如果出现,清除下浏览器的缓存就能解决

实战检验

因为生产环境和测试环境发布代码流程不同,所以先要把环境配置成一致先

需要做的事情很简单,把 nginx 中指向仓库地址,到时候从远端拉下代码即可

先修改 nginx 中的配置

1
2
3
4
5
6
server {
listen 7000;
# root /usr/share/nginx/html/dist
root /home/xxx/dist
...
}

再检查一下 nginx 配置是否 ok

1
nginx -t

接着重启 nginx

1
nginx -s reload

接着把代码提交到远端仓库,再上服务器进入 /home/xxx 目录下,git pull origin XX ,进入 dist 文件,查看打包后的 js

原js的hash值

我们修改在项目中打印一些日志,表示文件改动,这样 build 之后会打出不同 hash 的 js

git push origin XX

再次登录服务器,进入 /home/xxx 目录,再拉代码git pull origin xx

再次提交后的代码

发现,umi.b0f5511b.js 被删掉了,新生成的 umi.f8280c0e.js 在其中,dist 中是干净的源文件,这是为什么呢?

你 build 之后,是先删掉 dist 文件,生成的是一个干净的 dist,然后我的操作是:

  • git add .
  • git commit -m ‘XX’
  • git push origin ‘XX 分支’

我的操作中没有 pull 代码,而是直接 push 代码,这就意味着 dist 就是我本地的 dist,而非合并之后的

想想这种做法的缺点是多人开发时,pull 别人的代码后,merge 之后还要重新 build,才能再次提交

好险,还好没有逞英雄

谨言慎行是一辈子的学问

三句话测试你是否懂 git

这触发了笔者对 git 的新认知,结合平时经验,笔者觉得三个问题能测试别人对 git 的理解程度

  1. 你和同事基于同一 commit 开发,后续合并时,如何按照时间顺序显示提交记录
    • git rebase master XX(分支)
    • 获得更优雅的提交树
  2. 代码如何回滚
    • git reset –hard XX
    • 把当前代码指向另一个 commit 上
  3. 你开发代码,提交了好几个 commit,后续使用 git reset --hard xxxxx 把代码指针指回原始 commit ,并在这个 commit 上开发了一个功能,并提交了一个 commit,怎么找回之前提交的那好几个 commit
    • 首先使用 git reflog ,它能展示你之前所有的 git 操作
      • 比较 git log,它不仅包括了 git log 上的操作,而且它记录了被删除的 commit 记录和 reset 操作
    • git reset --hard XX
      • 将 git 指针指向回到原始代码前的那个 commit
    • git cherry-pick XX
      • 合并二次开发时的 commit
      • cherry-pick 意为取出,将二次开发时的 commit 取出放入主分支上