6 條 Git 實(shí)用技巧

本文首次發(fā)表在 6 條 Git 實(shí)用技巧 -- 泰曉科技

本文匯總最近一段時間用到的幾則 Git 實(shí)用小技巧,歡迎分享。

下面是大綱,文末有彩蛋 ^_^

1. 通過 Git Blame 找到誰動了某行代碼
2. 通過 Git Log 獲取某筆 Commit 或 Tag 的提交時間
3. 通過 Git Bisect 自動二分法快速定位問題
4. 用 Git Submodule Sync 更新 Git Submodule 的遠(yuǎn)程倉庫地址
5. 為不同 Git 倉庫配置不同的 Ssh Key
6. 用 Git Fetch 取代 Git Clone,實(shí)現(xiàn)斷點(diǎn)續(xù)傳

通過 git blame 找到誰動了某行代碼

定位到出錯的代碼行 以后,就可以通過 git blame 進(jìn)一步找到誰動了相關(guān)代碼,或者找到這筆改動的歷史背景,舉例如下:

$ cd linux-stable
$ git blame -L 50,50 init/main.c
78634061 (Frederic Weisbecker 2017-10-27 04:42:28 +0200 50) #include <linux/sched/isolation.h>

通過 git log 獲取某筆 commit 或 tag 的提交時間

在分析衰退時,如果找到了某筆變更,然后,又想進(jìn)一步確定這筆變更是在哪個版本(Tag)引入的,這個時候可以先找一下該 commit 的時間,然后再比對 Tag 的修訂時間。那么如何查看 commit 和 tag 的引入時間呢?以 HEAD 這筆 commit 舉例如下:

$ date -d @`git log -1 --format=%ct HEAD` +%Y%m%d-%H%M%S
20190719-172216

HEAD 替換為具體的 commit 和 tag 號即可獲得對應(yīng)時間。對于 Linux 而言,通常不需要這么復(fù)雜,在找到某個變更之后,用下面這個方法就可以確定該變更對應(yīng)的內(nèi)核主版本:

$ git show HEAD:Makefile

因為 Makefile 中記錄了內(nèi)核的版本號。

通過 git bisect 自動二分法快速定位問題

某個系統(tǒng),在開發(fā)過程中一直都沒測試出問題,突然有一天,發(fā)現(xiàn) Bug。這種蠻多情況是衰退,如果這個 Bug 的復(fù)現(xiàn)幾率很大的話,就可以直接用二分法快速定位了。git bisect 就可以輔助進(jìn)行自動二分法。

簡單的話,就是不停地告訴 git bisect,哪一個是好的,哪一個是壞的,如果有固定的復(fù)現(xiàn)腳本,那么在獲得第一對 bad, good 的 commit 后,就可以直接讓 git bisect 自動二分法。舉例說明:

$ git bisect start
$ git bisect bad efa5cf
$ git bisect good b6fcf0
$ git bisect run grep -q UCONFIG Makefile

說明:

  • efa5cf:第一個發(fā)現(xiàn)有問題的版本
  • b6fcf0:某個確認(rèn)沒問題的版本
  • grep -q UCONFIG Makefile:能找到 UCONFIG 就是好的,找不到就是有問題

在設(shè)定完 bad, good 后,git bisect 會自動切出中間某個版本,然后針對這個版本,可以進(jìn)行配置、編譯、運(yùn)行,然后根據(jù)測試結(jié)果設(shè)定該版本為 bad or good,例如:git bisect bad HEAD,以此類推,git bisect 會不停地切出中間版本,直到可以判斷第一個 bad 的版本,這個版本就是引入衰退的變更。

這個完整的測試過程如果可以自動化,就可以寫成腳本,作為 git bisect run 的參數(shù),這樣就可以避免手動跑測試。上面的 grep 命令是經(jīng)過初步分析后,找出的簡化策略。如果都能這樣通過檢索代碼變更本身就可以判斷問題,那確實(shí)可以省去不少力氣。

用 git submodule sync 更新 git submodule 的遠(yuǎn)程倉庫地址

前段我們把很多倉庫從 github 搬到了 gitee,搬完以后 Linux Lab 下的 .gitmodules.git/config 都得更新 url 地址,但是更新完以后并不能直接用,還得用 git submodule sync 同步一下:

  • 第 1 步,用 sed 替換 .gitmodules.git/config 中的 url
  • 第 2 步,執(zhí)行 git submodule sync

為不同 Git 倉庫配置不同的 ssh key

為優(yōu)化下載效率,最近把 Linux Lab 遷移到了碼云,配置了不同的 ssh 私鑰/公鑰。為了避免在命令行每次都要額外指定不同的參數(shù),可以添加一個配置文件。

例如,給碼云的私鑰文件命名為 gitee.id_rsa,把它放到 ~/.ssh 目錄下并修改權(quán)限。

$ chmod 600 ~/.ssh/gitee.id_rsa
$ chmod 700 ~/.ssh

之后,新增一個 ~/.ssh/config,加入如下配置:

$ cat ~/.ssh/config
Host gitee
  HostName gitee.com
  IdentityFile ~/.ssh/gitee.id_rsa
  User git

這樣就可以直接類似下面下載和上傳,而無需每次輸入密碼或指定密鑰了,同時省掉了 git@。

$ git clone gitee:aaaa/yyyy.git

$ cd cloud-lab
$ touch xxxx
$ git add xxxx
$ git commit -s -m "add xxxx"

$ git push gitee:aaaa/yyyy.git master

用 git fetch 取代 git clone,實(shí)現(xiàn)斷點(diǎn)續(xù)傳

git clone 下載大型代碼倉庫時,一旦網(wǎng)絡(luò)中斷,后果是哭爹喊娘,但是于事無補(bǔ),叫天天不應(yīng)。

因為 git clone 沒有實(shí)現(xiàn)斷點(diǎn)續(xù)傳,不知道開發(fā)者腦子“進(jìn)了什么水”?Linus 求罵嗎?;-)

沒關(guān)系,用 git fetch 可以實(shí)現(xiàn)類似效果,而且極其簡單。

先用 git init 創(chuàng)建一個空目錄:

$ mkdir test-repo
$ cd test-repo
$ git init

再在里頭用 git fetch 要 clone 的倉庫:

$ git fetch https://gitee.com/tinylab/cloud-lab.git
$ git checkout -b master FETCH_HEAD

git fetch 只能一個一個 branch fetch,fetch 完,把 FETCH_HEAD checkout 出來新建對應(yīng)的分支即可。如果 git fetch 中途中斷網(wǎng)絡(luò),可以再次 git fetch,git fetch 可以續(xù)傳,不至于一斷網(wǎng)就前功盡棄。

送您一枚免費(fèi)體驗卡

更多 Linux 精彩歡迎透過下方免費(fèi)體驗卡訪問『Linux 知識星球』:

『Linux 知識星球』免費(fèi)體驗卡
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容