同事和組長的一番對話引起了筆者對 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 中的配置
server {
listen 7000;
# root /usr/share/nginx/html/dist
root /home/jingqb-web/dist
...
}
再檢查一下 nginx 配置是否 ok
nginx -t
接著重啟 nginx
nginx -s reload
接著把程式碼提交到遠端倉庫,再上伺服器進入 /home/jingqb-web 目錄下,git pull origin XX
,進入 dist 檔案,檢視打包後的 js
我們修改在專案中列印一些日誌,表示檔案改動,這樣 build 之後會打出不同 hash 的 js
git push origin XX
再次登入伺服器,進入 /home/jingqb-web 目錄,再拉程式碼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 的理解程度
你和同事基於同一 commit 開發,後續合併時,如何按照時間順序顯示提交記錄
- git rebase master XX(分支)
- 獲得更優雅的提交樹
程式碼如何回滾
- git reset --hard XX
- 把當前程式碼指向另一個commit上
你開發程式碼,提交了好幾個 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 取出放入主分支上