Python腳本化Git的操作詳解
前言
如何判定此次測試是否達標,代碼覆蓋率是衡量的標準之一。前段時間,利用fastapi框架重寫了覆蓋率統(tǒng)計服務,核心其實就是先獲取全量代碼覆蓋率,然后通過diff操作統(tǒng)計增量代碼覆蓋率,當然要使用diff操作,避免不了與git打交道,那python如何操作gi t呢?
GitPython
GitPython庫提供了訪問和操作Git倉庫的方法,使得在Python環(huán)境下進行Git操作變得非常簡單。
安裝GitPython
使用pip包管理器來安裝GitPython:
pip install gitpython
克隆倉庫
在開始使用GitPython操作Git倉庫之前,我們首先需要克隆一個Git倉庫到本地。下面是一個簡單的示例代碼:
from git import Repo ? ? remote_url = 'https://github.com/username/repository.git' local_path = '/path/to/local/repository' ? ? Repo.clone_from(remote_url, local_path)
上述代碼中,設置遠程倉庫的URL和本地路徑,最后使用Repo.clone_from()方法來克隆遠程倉庫到本地。
當然,如果本地倉庫已經(jīng)存在,就不需要調用clone_from()進行克隆了,可以增加判斷,變?yōu)橄旅孢@樣
remote_url = 'https://github.com/username/repository.git'
local_path = '/path/to/local/repository'
if os.path.exists(local_path):
repo = Repo(local_path)
else:
repo = Repo.clone_from(remote_url, local_path)
我們判斷了本地倉庫是否存在,不存在進行克隆,如果存在直接實例化
獲取分支信息
接下來,我們將獲取已克隆倉庫的所有分支信息。
from git import Repo
?
repo_path = '/path/to/your/git/repository'
?
repo = Repo(repo_path)
branches = repo.heads
?
for branch in branches:
print(f"Branch: {branch.name}, Commit ID: {branch.commit}")
通過heads來獲取所有分支,然后遍歷輸出分支名稱和對應的 commit ID
提交更改
要提交更改,我們需要添加文件到暫存區(qū),并提交更改。
from git import Repo
?
repo_path = '/path/to/your/git/repository'
?
repo = Repo(repo_path)
repo.index.add(['file1.py', 'file2.py'])
repo.index.commit("Commit message")
這部分功能,在代碼覆蓋率統(tǒng)計中未用到,這里做一個記錄了解吧。
查看狀態(tài)
from git import Repo ? ? ? repo_path = '/path/to/your/git/repository' ? repo = Repo(repo_path) ? repo_status = repo.git.status() print(repo_status)
代碼中通過status來查看狀態(tài),其實和gi t的命令是一樣的。
切換分支和合并代碼
from git import Repo
?
?
?
repo_path = '/path/to/your/git/repository'
repo = Repo(repo_path)
?
repo.git.checkout('develop')
?
repo.git.merge('feature-branch')
?
以上代碼使用checkout切換到指定分支然后使用merge合并代碼。
獲取遠程倉庫的最新變更
from git import Repo ? ? repo_path = '/path/to/your/git/repository' ? repo = Repo(repo_path) repo.fetch()
從遠程倉庫獲取最新的提交記錄、分支和文件,但并不自動合并到本地代碼。它只是將遠程倉庫的最新變更拉取到本地,但不會自動更新工作目錄中的文件。這意味著在執(zhí)行 git fetch 后,需要手動進行合并或重新基于遠程分支進行開發(fā)。
diff操作
from git import Repo ? ? repo_path = '/path/to/your/git/repository' ? repo = Repo(repo_path) repo.git.diff(base_branch, current_branch)
使用 git.diff() 方法比較了 base_branch 和 current_branch 之間的差異
實戰(zhàn)案例
下面講一下筆者統(tǒng)計增量覆蓋率的核心代碼
def get_diff(self, current_branch: str, base_branch: str = "origin/master"):
"""獲取版本之間代碼差異"""
diff = self.repo.git.diff(base_branch, current_branch).split("\n")
?
ret = {}
file_name = ""
diff_lines = []
current_line = 0
for line in diff:
if line.startswith("diff --git"):
if file_name != "":
ret[file_name] = diff_lines
file_name = re.findall("b/(\S+)$", line)[0]
diff_lines = []
current_line = 0
?
elif re.match("@@ -\d+,\d+ +(\d+),\d+ @@", line):
match = re.match("@@ -\d+,\d+ +(\d+),\d+ @@", line)
current_line = int(match.group(1)) - 1
?
elif line.startswith("-"):
continue
elif line.startswith("+") and not line.startswith("+++"):
current_line += 1
diff_lines.append(current_line)
else:
current_line += 1
ret[file_name] = diff_lines
return ret
這段用于獲取兩個分支之間的代碼差異。
get_diff方法接受兩個參數(shù)current_branch和base_branch,分別表示當前分支和基準分支,默認為 "origin/master"。
- 通過調用
self.repo.git.diff(base_branch, current_branch)方法獲取基準分支和當前分支之間的代碼差異,并將結果按行拆分成列表。
- 使用一個字典
ret來存儲代碼差異的信息,其中鍵為文件名,值為差異的行號列表。
遍歷代碼差異行,根據(jù)行的內容進行不同的處理:
- 如果遇到以 "diff --git" 開頭的行,則表示開始處理一個新文件的差異,提取文件名。
- 如果匹配到以 "@@ -\d+,\d+ +(\d+),\d+ @@" 格式的行,則提取新版本代碼的起始行號。
- 如果遇到以 "-" 開頭的行,則表示該行在基準分支中有但在當前分支中沒有,忽略。
- 如果遇到以 "+" 開頭且不以 "+++" 開頭的行,則表示該行在當前分支中新增,記錄當前行號并添加到差異行列表中。
- 其他情況下,當前行號遞增。
- 最后將最后一個文件的差異行信息添加到字典中,并返回整體的差異信息。
這段代碼的作用是從 Git 中提取兩個版本之間的代碼差異信息,并以文件名及差異行號的形式存儲返回。
最后
GitPython極大方便了python操作gi t,讓我更快速的實現(xiàn)了增量代碼覆蓋率的統(tǒng)計工作,當然這里只是筆者在實現(xiàn)覆蓋率統(tǒng)計工作中用到的GitPython相關的方法,還有更多方法。
以上就是Python腳本化Git的操作詳解的詳細內容,更多關于Python腳本化Git 的資料請關注腳本之家其它相關文章!
相關文章
python實現(xiàn)自動發(fā)送報警監(jiān)控郵件
這篇文章主要為大家詳細介紹了python實現(xiàn)自動發(fā)送報警監(jiān)控郵件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06
Python實現(xiàn)csv文件(點表和線表)轉換為shapefile文件的方法
這篇文章主要介紹了Python實現(xiàn)csv文件(點表和線表)轉換為shapefile文件的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10
昨晚我用python幫隔壁小姐姐P證件照然后發(fā)現(xiàn)
大家好,我是Lex 喜歡欺負超人那個Lex 建議大家收藏哦,以后幫小姐姐P自拍,證件照,調尺寸,背景,摳圖,直接10行代碼搞定,瞬間高大上2021-08-08
Python 中PyQt5 點擊主窗口彈出另一個窗口的實現(xiàn)方法
這篇文章主要介紹了Python 中PyQt5 點擊主窗口彈出另一個窗口的實現(xiàn)方法,本文代碼實例圖文相結合的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07
Tensorflow 定義變量,函數(shù),數(shù)值計算等名字的更新方式
今天小編就為大家分享一篇Tensorflow 定義變量,函數(shù),數(shù)值計算等名字的更新方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02

