1. 程式人生 > 程式設計 >git log根據特定條件查詢日誌並統計修改的程式碼行數

git log根據特定條件查詢日誌並統計修改的程式碼行數

前言

隨著年齡的增長和知識的積累,最近常常有種豁然開朗的感覺,或者對一個已經存在的事物突然有了新的認識,比如統計這個詞很早就接觸了,從沒考慮過它是什麼意思,而這篇總結的題目中用了統計一詞,第一感覺應該是彙總、記錄的意思,後來去查了詞條定義,也確實就是類似的解釋,從沒有刻意去學這個詞的含義,但是在每天的生活中已經潛移默化地歸納、總結出來了。

想要統計就得有資料來源,而 git log 命令恰恰就能提供這個資料來源,git log 本身就是一個顯示日誌的命令,日誌記錄的是程式碼庫變化的資料,類似於描述程式碼庫變化的 “史書”,想要描述歷史就需要大量的資料支撐,想要統計修改的程式碼行數,只要我們從歷史記錄中找到需要計算的部分就可以了。

git log

在統計之前我們需要先整理資料,雜亂無章的資料不是不能統計,只是計算起來更加的麻煩,所以在統計前需要先將資料規範化,所以我們需要先學習一下 git log 的相關操作。

我們以 redis 開源庫為例,切換到 6.0 分支,提交記錄定位到 7bf665f125a4771db095c83a7ad6ed46692cd314,以此為資料來源,學習一下git log 的常用的查詢方法,其實使用不同的條件查詢就是整理、歸類資料的過程。

git log 的用法多種多樣,我們主要關心兩個大類,分別是條件篩選和顯示格式。

條件篩選

git log 條件篩選的選項非常多,使用條件篩選的選項會影響顯示的提交記錄的範圍,查詢到想要顯示的提交記錄。

查詢最近幾條log

使用 -number 引數可以查詢最近幾條提交提交記錄:

$ git log -3
commit 7bf665f125a4771db095c83a7ad6ed46692cd314 (HEAD -> 6.0,tag: 6.0.6,origin/6.0)
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 14:00:20 2020 +0300

 Redis 6.0.6.

commit a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 15:33:21 2020 +0300

 Run daily CI on PRs to release a branch

commit e15528bf1da1f1232fd08801ad382c915be94662
Author: Itamar Haber <[email protected]>
Date: Thu Jul 16 21:31:36 2020 +0300

 Adds SHA256SUM to redis-stable tarball upload

 (cherry picked from commit 5df0a64d30e7815c0a4a75a80f165fdee0bd1db6)

查詢指定作者提交

使用 --author 引數可以查詢指定作者的提交記錄:

Albert@DESKTOP-6746UC3 MINGW64 /d/data/maingit/redis (6.0)
$ git log -2 --author='Oran Agra'
commit 7bf665f125a4771db095c83a7ad6ed46692cd314 (HEAD -> 6.0,origin/6.0)
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 14:00:20 2020 +0300

 Redis 6.0.6.

commit a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 15:33:21 2020 +0300

 Run daily CI on PRs to release a branch

查詢指定時間段的日誌

這個可選引數比較多,比如 --since--until--before--after 等等,從意思很容易分辨怎麼使用:

查詢2020-01-01到2020-04-01的提交記錄

$ git log -2 --after=2020-01-01 --before=2020-04-01
commit 957e917a84ac9979f18145a4d0b53386f5ce4fd9 (tag: 6.0-rc3)
Author: antirez <[email protected]>
Date: Tue Mar 31 17:56:04 2020 +0200

 Redis 6.0-RC3.

commit ef1b1f01a84e969ea368e7fdbaf0d10615743269
Author: antirez <[email protected]>
Date: Tue Mar 31 17:41:23 2020 +0200

 cast raxSize() to avoid warning with format spec.

恰好逮到了原作者的提交~

查詢1年前的提交記錄

$ git log -2 --until=1.year.ago
commit 86aade9a024c3582665903d0cc0c5692c6677cfd
Merge: 89ad0ca56 3bfcae247
Author: Salvatore Sanfilippo <[email protected]>
Date: Thu Sep 5 13:30:26 2019 +0200

 Merge pull request #6364 from oranagra/fix_module_aux_when

 Fix to module aux data rdb format for backwards compatibility with old check-rdb

commit 3bfcae247a1c51788940bd4d2f32751ead451e42
Author: Oran Agra <[email protected]>
Date: Thu Sep 5 14:11:37 2019 +0300

 Fix to module aux data rdb format for backwards compatibility with old check-rdb

 When implementing the code that saves and loads these aux fields we used rdb
 format that was added for that in redis 5.0,but then we added the 'when' field
 which meant that the old redis-check-rdb won't be able to skip these.
 this fix adds an opcode as if that 'when' is part of the module data.

查詢包含指定描述內容的提交記錄

這裡用可以使用 --grep 引數,可以過濾出包含指定內容的提交記錄,這裡指的是在 commit 描述中篩選符合條件的提交,比如查詢提交描述中包含 client 的提交記錄:

$ git log -2 --grep='client'
commit 0f75036c07db48dfcf605e090216a4447edc38fc
Author: Wen Hui <[email protected]>
Date: Wed Jul 15 05:38:47 2020 -0400

 correct error msg for num connections reaching maxclients in cluster mode (#7444)


 (cherry picked from commit d85af4d6f5fbe9cb9787b81583627cd74b47f838)

commit f89f50dbd06247677b8cb3927cbb88c1b5384061
Author: Oran Agra <[email protected]>
Date: Tue Jul 14 20:21:59 2020 +0300

 diskless master disconnect replicas when rdb child failed (#7518)

 in case the rdb child failed,crashed or terminated unexpectedly redis
 would have marked the replica clients with repl_put_online_on_ack and
 then kill them only after a minute when no ack was received.

 it would not stream anything to these connections,so the only effect of
 this bug is a delay of 1 minute in the replicas attempt to re-connect.

 (cherry picked from commit a176cb56a3c0235adddde33fcbaee2369a5af73e)

查詢指定分支的提交記錄

使用 git log 預設查詢的是當前分支的提交記錄,如果想查詢其他分支的記錄直接在命令後面加上分支名字就行,比如查詢 arm 分支上的提交記錄:

$ git log -2 arm
commit 7329cc39818a05c168e7d1e791afb03c089f1933 (origin/arm,arm)
Author: Salvatore Sanfilippo <[email protected]>
Date: Sun Feb 19 15:07:08 2017 +0000

 ARM: Avoid fast path for BITOP.

 GCC will produce certain unaligned multi load-store instructions
 that will be trapped by the Linux kernel since ARM v6 cannot
 handle them with unaligned addresses. Better to use the slower
 but safer implementation instead of generating the exception which
 should be anyway very slow.

commit 4e9cf4cc7ed4b732fc4bb592f19ceb41d132954e
Author: Salvatore Sanfilippo <[email protected]>
Date: Sun Feb 19 15:02:37 2017 +0000

 ARM: Use libc malloc by default.

 I'm not sure how much test Jemalloc gets on ARM,moreover
 compiling Redis with Jemalloc support in not very powerful
 devices,like most ARMs people will build Redis on,is extremely
 slow. It is possible to enable Jemalloc build anyway if needed
 by using "make MALLOC=jemalloc".

其實在 git 體系中,分支名、commit、標籤等擁有幾乎相同的含義,所以在很多場景下可以擴充套件互換,比如 git log 後面加上分支名就可以查詢指定分支的提交記錄,如果加上 commit 就會查詢這個 commit 之前的提交記錄,如果加上標籤,就可以查詢這個標籤之前的提交記錄,比如我們加一個 commit 試試:

$ git log -2 7329cc39818a05c168e7d1e791afb03c089f1933
commit 7329cc39818a05c168e7d1e791afb03c089f1933 (origin/arm,is extremely
 slow. It is possible to enable Jemalloc build anyway if needed
 by using "make MALLOC=jemalloc".

因為 commit id 就是之前的 arm 分支最新的記錄,所以這個命令等價於 git log -2 arm

查詢指定 commit 之間的提交記錄

如果想查詢兩個 commit 之前的提交記錄,可以將兩個 commit id 依次放在命令後面並用 .. 連線就可以了,格式為 git log commit1..commit2,需要注意的是這樣查詢出來的提交記錄列表中不包含 commit1,其實列舉出的就是 commit1 之後又做了哪些修改提交。

$ git log e15528bf1da1f1232fd08801ad382c915be94662..7bf665f125a4771db095c83a7ad6ed46692cd314
commit 7bf665f125a4771db095c83a7ad6ed46692cd314 (HEAD -> 6.0,origin/6.0)
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 14:00:20 2020 +0300

 Redis 6.0.6.

commit a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 15:33:21 2020 +0300

 Run daily CI on PRs to release a branch

這個特性有一個應用就是在 merge 分支之前可以查詢究竟會 merge 哪些記錄,常見的用法比如 git log feature..dev 就是列舉出 feature 分支合併到 dev 分支將要合併的提交記錄有哪些。

$ git log 6.0..unstable
commit 324e22accf457edc996971bc97f5474349cd7c4c (unstable)
Author: antirez <[email protected]>
Date: Fri Dec 20 12:29:02 2019 +0100

 Fix ip and missing mode in RM_GetClusterNodeInfo().

查詢指定檔案的提交記錄

查詢指定檔案的提交記錄一般直接在 git log 命令後面跟上檔名就可以,但是為了避免和分支名產生分歧,所以通常在檔名前面加上 -- 用來區分,-- 這個識別符號就是用來防止混淆的,放在 -- 前面的是分支名,放在後面的是檔名,相同的作用不僅僅在 git log 命令中,在其他命令比如 git checkout 中也有相同的用法。

$ git log -2 -- redis.conf
commit 7a536c2912be1fd9f62b26b7022a00644c88ef8b
Author: Yossi Gottlieb <[email protected]>
Date: Fri Jul 10 11:33:47 2020 +0300

 TLS: Session caching configuration support. (#7420)

 * TLS: Session caching configuration support.
 * TLS: Remove redundant config initialization.

 (cherry picked from commit 3e6f2b1a45176ac3d81b95cb6025f30d7aaa1393)

commit 8312aa27d47c0befcf69eb74d0a5dc19745ffd32
Author: antirez <[email protected]>
Date: Mon Jun 22 11:21:21 2020 +0200

 Clarify maxclients and cluster in conf. Remove myself too.

 (cherry picked from commit 59fd178014c7cca1b0c668b30ab0d991dd3030f3)

顯示格式

git log 除了可以篩選提交記錄,還可以控制顯示格式,普通不加引數,會顯示作者、郵件、提交描述資訊、日期等資訊。

通過添

$ git log -1
commit 7bf665f125a4771db095c83a7ad6ed46692cd314 (HEAD -> 6.0,origin/6.0)
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 14:00:20 2020 +0300

 Redis 6.0.6.

加引數可以控制和改變顯示格式,下面來看幾條常見的

顯示單行資訊

git log 預設會顯示多行資訊,使用 --oneline 後每條提交記錄只顯示一行資訊,可以在一螢幕中檢視到更多的資訊

$ git log -10 --oneline
7bf665f12 (HEAD -> 6.0,origin/6.0) Redis 6.0.6.
a5696bdf4 Run daily CI on PRs to release a branch
e15528bf1 Adds SHA256SUM to redis-stable tarball upload
e28aa99af Support passing stack allocated module strings to moduleCreateArgvFromUserFormat (#7528)
305143004 Send null for invalidate on flush (#7469)
29b20fd52 Notify systemd on sentinel startup (#7168)
5b3668121 Add registers dump support for Apple silicon (#7453)
0f75036c0 correct error msg for num connections reaching maxclients in cluster mode (#7444)
b1a01fda9 Fix command help for unexpected options (#7476)
83f55f61a Refactor RM_KeyType() by using macro. (#7486)

顯示每條記錄中檔案修改的具體行數和行體統計

使用 --stat 引數就可以顯示每條記錄的中修改檔案的具體行數和行數統計

$ git log -2 --stat
commit 7bf665f125a4771db095c83a7ad6ed46692cd314 (HEAD -> 6.0,origin/6.0)
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 14:00:20 2020 +0300

 Redis 6.0.6.

 00-RELEASENOTES | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/help.h | 4 +-
 src/version.h | 2 +-
 3 files changed,248 insertions(+),3 deletions(-)

commit a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 15:33:21 2020 +0300

 Run daily CI on PRs to release a branch

 .github/workflows/daily.yml | 6 ++++--
 1 file changed,4 insertions(+),2 deletions(-)

顯示每條提交記錄中檔案的增加行數和刪除行數

使用 --numstat 引數會把 --stat 引數中合併顯示的修改行數拆分成增加行數和刪除行數

$ git log -2 --numstat
commit 7bf665f125a4771db095c83a7ad6ed46692cd314 (HEAD -> 6.0,origin/6.0)
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 14:00:20 2020 +0300

 Redis 6.0.6.

245 0 00-RELEASENOTES
2 2 src/help.h
1 1 src/version.h

commit a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
Author: Oran Agra <[email protected]>
Date: Sun Jul 19 15:33:21 2020 +0300

 Run daily CI on PRs to release a branch

4 2 .github/workflows/daily.yml

依次羅列各提交記錄中每個檔案中增加的行數和刪除的行數

要想達到這個目的需要用到 --prety=tformat: --numstat 引數,這樣的顯示格式便於統計

$ git log -2 --pretty=tformat: --numstat
245 0 00-RELEASENOTES
2 2 src/help.h
1 1 src/version.h
4 2 .github/workflows/daily.yml

統計修改的程式碼行數

有了前面的鋪墊,想要統一修改的行數就容易了,只要配合 awk 工具就可以完成統計了

$ $ git log -2 --pretty=tformat: --numstat | awk '{adds += $1; subs += $2; diffs += $1 - $2} END {printf "added lines: %s removed lines: %s,diff lines: %s\n",adds,subs,diffs}'
added lines: 252 removed lines: 5,diff lines: 247

還可以統計兩個分支相差的程式碼行數

$ git log 6.0..unstable --pretty=tformat: --numstat | awk '{adds += $1; subs += $2; diffs += $1 - $2} END {printf "added lines: %s removed lines: %s,diffs}'
added lines: 5 removed lines: 2,diff lines: 3

到這裡可以發現前面的知識都可以用上,前面篩選的引數變了,得到的結果就變了,我們可以根據需求來調整不同的引數

總結

  • git log 就是一部程式碼庫記錄的“史書”,對於曾經所做的修改可以做到有史可查
  • git log 的選項引數可以分為篩選引數和格式引數,篩選引數可以選擇記錄範圍,格式引數可以控制顯示樣式
  • 統計就是按照一定規律來將資料進行彙總,在進行彙總前需要將資料進行整理,這樣彙總的工作才會更加順利

到此這篇關於git log根據特定條件查詢日誌並統計修改的程式碼行數的文章就介紹到這了,更多相關git log統計修改程式碼行數內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!