当前位置: 首页 > news >正文

Python 脚本化 Git 操作:简单、高效、无压力

前言

如何判定此次测试是否达标,代码覆盖率是衡量的标准之一。前段时间,利用fastapi框架重写了覆盖率统计服务,核心其实就是先获取全量代码覆盖率,然后通过diff操作统计增量代码覆盖率,当然要使用diff操作,避免不了与git打交道,那python如何操作gi t呢?

GitPython

GitPython库提供了访问和操作Git仓库的方法,使得在Python环境下进行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()方法来克隆远程仓库到本地。

当然,如果本地仓库已经存在,就不需要调用clone_from()进行克隆了,可以增加判断,变为下面这样

 
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

提交更改

要提交更改,我们需要添加文件到暂存区,并提交更改。

 
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")

这部分功能,在代码覆盖率统计中未用到,这里做一个记录了解吧。

查看状态

 
from git import Repo
​
​
​
repo_path = '/path/to/your/git/repository'
​
repo = Repo(repo_path)
​
repo_status = repo.git.status()
print(repo_status)

代码中通过status来查看状态,其实和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()

从远程仓库获取最新的提交记录、分支和文件,但并不自动合并到本地代码。它只是将远程仓库的最新变更拉取到本地,但不会自动更新工作目录中的文件。这意味着在执行 git fetch 后,需要手动进行合并或重新基于远程分支进行开发。

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_branchcurrent_branch 之间的差异

实战案例

下面讲一下笔者统计增量覆盖率的核心代码

 
    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 = 0for line in diff:if line.startswith("diff --git"):if file_name != "":ret[file_name] = diff_linesfile_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("-"):continueelif line.startswith("+") and not line.startswith("+++"):current_line += 1diff_lines.append(current_line)else:current_line += 1ret[file_name] = diff_linesreturn ret

这段用于获取两个分支之间的代码差异。

  • get_diff 方法接受两个参数 current_branchbase_branch,分别表示当前分支和基准分支,默认为 "origin/master"。
  • 通过调用 self.repo.git.diff(base_branch, current_branch) 方法获取基准分支和当前分支之间的代码差异,并将结果按行拆分成列表。
  • 使用一个字典 ret 来存储代码差异的信息,其中键为文件名,值为差异的行号列表。
  • 遍历代码差异行,根据行的内容进行不同的处理:

    • 如果遇到以 "diff --git" 开头的行,则表示开始处理一个新文件的差异,提取文件名。
    • 如果匹配到以 "@@ -\d+,\d+ +(\d+),\d+ @@" 格式的行,则提取新版本代码的起始行号。
    • 如果遇到以 "-" 开头的行,则表示该行在基准分支中有但在当前分支中没有,忽略。
    • 如果遇到以 "+" 开头且不以 "+++" 开头的行,则表示该行在当前分支中新增,记录当前行号并添加到差异行列表中。
    • 其他情况下,当前行号递增。
  • 最后将最后一个文件的差异行信息添加到字典中,并返回整体的差异信息。

这段代码的作用是从 Git 中提取两个版本之间的代码差异信息,并以文件名及差异行号的形式存储返回。

最后

GitPython极大方便了python操作gi t,让我更快速的实现了增量代码覆盖率的统计工作,当然这里只是笔者在实现覆盖率统计工作中用到的GitPython相关的方法,还有更多方法,可以翻阅官方文档:gitpython.readthedocs.io/en/stable/

 下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

软件测试面试小程序
被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux 6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 10、开放性测试题,11、安全测试,12、计算机基础

​编辑资料获取方式 :xiaobei_upup,添加时备注“csdn alex”

http://www.lryc.cn/news/355920.html

相关文章:

  • 手搓顺序表(C语言)
  • 一文搞懂oracle事务提交以及脏数据落盘的原则
  • OceanBase:列存储
  • Rust:WIndows 环境下交叉编译 Linux 平台程序
  • 从零学爬虫:使用比如说说解析网页结构
  • C#数据类型变量、常量
  • Java高级面试问题及答案
  • 出现 Transaction rolled back because it has been marked as rollback-only 解决方法
  • 数据结构算法题day03
  • 深入分析C#中的“编写器”概念——代码修改、注解与重构
  • uview1.0 u-form表单回显校验不通过
  • 监控员工电脑的软件有哪些,不得不说这几款电脑监控软件太好用了
  • 【MySQL精通之路】索引优化(2)
  • VUE3 学习笔记(5):数组处理、计算属性与函数、class与Style绑定
  • 基于springboot实现大学生一体化服务平台系统项目【项目源码+论文说明】
  • 惠海 H6902B 升压恒流芯片 太阳能 风扇灯 应急灯 支持3.7V 5V 7.4V
  • 体验SmartEDA的高效与便捷,电子设计从未如此简单
  • LangChain笔记
  • 金融序列的布朗运动
  • 利用ChatGPT辅助数学建模竞赛:理清思路、解题技巧与实战经验
  • Java基础——Optional
  • Mask R-CNN实战
  • 02--SpringBoot自动装配原理
  • 【加密与解密(第四版)】第十二章笔记
  • 高并发幂等计数器【面试真题】
  • 设计软件有哪些?建模和造型工具篇(3),渲染100邀请码1a12
  • 无人机+EasyDSS互联网视频平台:构建秸秆焚烧监控的“天眼”系统
  • 【UE5.1 角色练习】06-角色发射火球-part2
  • 多系统集成的项目周期为何普遍较长?
  • 【LaTex】11 ACM参考文献顺序引用 - 解决 ACM-Reference-Format 顺序不符合论文实际引用顺序的问题