【Python】快速判断两个commit 是否存在cherry-pick 关系

embedded/2024/9/24 14:32:14/

判断两个提交是否有 cherry-pick 关系的 Python 脚本,可以基于以下三种常见情况进行优化:

  1. Commit Hash 一致:如果两个提交的 hash 完全相同,那么它们是相同的提交。

  2. Commit Title 存在关联:如果两个提交的 commit message 提及了相同的原始提交,例如 cherry picked from commit <hash>,可以通过解析提交信息来确定关联。

  3. Commit 变更内容一致:即使 hashtitle 不同,如果两个提交的代码变更完全一致,则可能是 cherry-pick 关系。

另外,还有可能存在其他场景,比如提交的父节点不同,但内容一致,这也是一种 cherry-pick 的表现。

基于以上情况,下面是一个优化的 Python 脚本:

Python 脚本

V1版本
import subprocess
import redef run_git_command(args):"""运行 Git 命令并返回输出结果。"""try:result = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)if result.returncode != 0:print(f"Error running command {args}: {result.stderr}")return Nonereturn result.stdout.strip()except Exception as e:print(f"An error occurred: {e}")return Nonedef get_commit_message(commit_hash):"""获取提交信息(commit message)。"""return run_git_command(["git", "log", "-1", "--pretty=%B", commit_hash])def get_diff(commit_hash):"""获取提交的代码差异(diff)。"""return run_git_command(["git", "diff-tree", "--no-commit-id", "--patch", "-r", commit_hash])def check_cherry_pick_message(commit1_message, commit2_message):"""检查提交信息中是否提到 cherry-pick 的关联。"""cherry_pick_pattern = re.compile(r'cherry\s+picked\s+from\s+commit\s+([a-f0-9]{40})')# 检查第一个提交信息是否提到 cherry-pick 的原始提交match1 = cherry_pick_pattern.search(commit1_message)match2 = cherry_pick_pattern.search(commit2_message)if match1 and match2 and match1.group(1) == match2.group(1):return True# 或者检查一个提交是否提到另一个提交if match1 and match1.group(1) in commit2_message:return Trueif match2 and match2.group(1) in commit1_message:return Truereturn Falsedef compare_commit_diffs(commit1, commit2):"""比较两个提交的代码变更是否一致。"""diff1 = get_diff(commit1)diff2 = get_diff(commit2)if diff1 is None or diff2 is None:return Falsereturn diff1 == diff2def compare_commits(commit1, commit2):"""综合比较两个提交是否有 cherry-pick 关系。"""# 1. 检查 commit hash 是否相同if commit1 == commit2:print(f"Commits {commit1} and {commit2} are identical (same hash).")return True# 2. 检查 commit message 是否提到 cherry-pick 关系commit1_message = get_commit_message(commit1)commit2_message = get_commit_message(commit2)if commit1_message is None or commit2_message is None:print("Failed to get commit messages.")return Falseif check_cherry_pick_message(commit1_message, commit2_message):print(f"Commits {commit1} and {commit2} have a cherry-pick relation based on commit message.")return True# 3. 检查代码变更是否完全一致if compare_commit_diffs(commit1, commit2):print(f"Commits {commit1} and {commit2} have identical code changes (cherry-pick relation likely).")return Trueprint(f"Commits {commit1} and {commit2} do not have a clear cherry-pick relation.")return Falseif __name__ == "__main__":# 输入需要比较的两个 commit hashcommit_hash_1 = input("Enter the first commit hash: ")commit_hash_2 = input("Enter the second commit hash: ")if compare_commits(commit_hash_1, commit_hash_2):print(f"Commits {commit_hash_1} and {commit_hash_2} are related (cherry-pick detected).")else:print(f"Commits {commit_hash_1} and {commit_hash_2} are not related (no cherry-pick detected).")

如果存在编码错误

可以使用下方脚本尝试

V2版本
python">import subprocess
import redef run_git_command(args):"""运行 Git 命令并返回输出结果。"""try:result = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding='utf-8')if result.returncode != 0:print(f"Error running command {args}: {result.stderr}")return Nonereturn result.stdout.strip()except Exception as e:print(f"An error occurred: {e}")return Nonedef get_commit_message(commit_hash):"""获取提交信息(commit message)。"""return run_git_command(["git", "log", "-1", "--pretty=%B", commit_hash])def get_diff(commit_hash):"""获取提交的代码差异(diff)。"""try:return run_git_command(["git", "diff-tree", "--no-commit-id", "--patch", "-r", commit_hash])except Exception as e:print(f"An error occurred while getting diff for {commit_hash}: {e}")return Nonedef check_cherry_pick_message(commit1_message, commit2_message):"""检查提交信息中是否提到 cherry-pick 的关联。"""cherry_pick_pattern = re.compile(r'cherry\s+picked\s+from\s+commit\s+([a-f0-9]{40})')match1 = cherry_pick_pattern.search(commit1_message)match2 = cherry_pick_pattern.search(commit2_message)if match1 and match2 and match1.group(1) == match2.group(1):return Trueif match1 and match1.group(1) in commit2_message:return Trueif match2 and match2.group(1) in commit1_message:return Truereturn Falsedef compare_commit_diffs(commit1, commit2):"""比较两个提交的代码变更是否一致。"""diff1 = get_diff(commit1)diff2 = get_diff(commit2)if diff1 is None or diff2 is None:return Falsereturn diff1 == diff2def compare_commits(commit1, commit2):"""综合比较两个提交是否有 cherry-pick 关系。"""if commit1 == commit2:print(f"Commits {commit1} and {commit2} are identical (same hash).")return Truecommit1_message = get_commit_message(commit1)commit2_message = get_commit_message(commit2)if commit1_message is None or commit2_message is None:print("Failed to get commit messages.")return Falseif check_cherry_pick_message(commit1_message, commit2_message):print(f"Commits {commit1} and {commit2} have a cherry-pick relation based on commit message.")return Trueif compare_commit_diffs(commit1, commit2):print(f"Commits {commit1} and {commit2} have identical code changes (cherry-pick relation likely).")return Trueprint(f"Commits {commit1} and {commit2} do not have a clear cherry-pick relation.")return Falsedef validate_commit_hash(commit_hash):"""验证提交 hash 是否是有效的 SHA-1 hash。"""if re.fullmatch(r'[a-fA-F0-9]{40}', commit_hash):return Trueelse:print(f"Invalid commit hash: {commit_hash}")return Falseif __name__ == "__main__":commit_hash_1 = input("Enter the first commit hash: ")commit_hash_2 = input("Enter the second commit hash: ")if validate_commit_hash(commit_hash_1) and validate_commit_hash(commit_hash_2):if compare_commits(commit_hash_1, commit_hash_2):print(f"Commits {commit_hash_1} and {commit_hash_2} are related (cherry-pick detected).")else:print(f"Commits {commit_hash_1} and {commit_hash_2} are not related (no cherry-pick detected).")else:print("Please enter valid commit hashes.")

脚本的工作原理

  1. Commit Hash 一致:脚本首先检查两个提交的 hash 是否完全相同。如果相同,它们肯定是相同的提交。

  2. Commit Title 存在关联:通过正则表达式匹配 commit message 中的 cherry picked from commit <hash> 字符串,检查一个提交是否从另一个提交进行了 cherry-pick。如果 commit message 中存在这样的引用,则说明它们有 cherry-pick 关系。

  1. Commit 变更内容一致:如果提交的 hashmessage 没有明显的关联,脚本通过获取两个提交的代码变更(git diff-tree)并对比差异内容是否完全相同。如果两个提交的代码变更完全一致,它们很有可能是 cherry-pick 关系。

使用说明

  1. 将脚本保存为 compare_commits.py

  2. 在 Git 仓库的根目录执行以下命令:

     

    python3 compare_commits.py

  3. 输入两个需要比较的提交哈希(commit hash)。

处理的场景

  • 两个提交的 commit hash 完全相同(直接相同的提交)。

  • commit message 提到 cherry-pick 的引用关系。

  • commit hashcommit message 不同,但代码变更内容完全相同。

这个脚本可以帮助识别 cherry-pick 关系的多种常见情况,并可以扩展以处理更多特殊情况。你可以尝试运行这个脚本,看看能否正确检测出 cherry-pick 关系。

运行示例


http://www.ppmy.cn/embedded/116130.html

相关文章

2024全球科技品牌价值榜50强:苹果第一

根据《Brand Finance 2024年全球最具价值科技品牌榜单报告》&#xff0c;中国品牌在社交媒体、电子和电器行业表现卓越。 全球排名前三的是&#xff1a;苹果、微软以及 Google。国内前几的是&#xff1a;抖音、微信和华为&#xff0c;分为位于第五、十一、十五位。 英伟达在人工…

英特尔®以太网网络适配器E810-CQDA1 / E810-CQDA2 网卡 规格书 e810 网卡 规格书 Intel100G E810 网卡 白皮书

英特尔以太网800系列网络适配器 英特尔以太网网络适配器E810-CQDA1 / CQDA2 在10到100Gbps的以太网速度下实现高效的工作负载优化性能 关键特性 •单、双端口QSFP28 •应用设备队列(ADQ) •PCI Express (PCIe) 4.0 x16 •动态设备个性化(DDP) •以太网端口配置工具(EPC…

npm install报错npm ERR Could not resolve dependency: npm ERR peer... 依赖冲突

报错原因 在新版本的npm中&#xff0c;默认情况下&#xff0c;npm install遇到冲突的peerDependencies时将失败。 解决办法 使用--force或--legacy-peer-deps可解决这种情况。 --force 会无视冲突&#xff0c;并强制获取远端npm库资源&#xff0c;当有资源冲突时覆盖掉原先的…

24 C 语言常用的字符串处理函数详解:strlen、strcat、strcpy、strcmp、strchr、strrchr、strstr、strtok

目录 1 strlen 1.1 函数原型 1.2 功能说明 1.3 案例演示 1.4 注意事项 2 strcat 2.1 函数原型 2.2 功能说明 2.3 案例演示 2.4 注意事项 3 strcpy 3.1 函数原型 3.2 功能说明 3.3 案例演示 3.4 注意事项 4 strcmp 4.1 函数原型 4.2 功能说明 4.3 案例演示 …

python数学运算符

加&#xff1a; 减&#xff1a;- 乘&#xff1a;* 除&#xff1a;/ 整除&#xff1a;// 取余&#xff1a;% 平方&#xff1a;** 示例如下&#xff1a; num 7 # 初始化一个整型变量num num // 5 #对num进行整除操作 print(num) #打印的num值为1num % 1 …

js 深入理解类-class

目录 概述1. 类的定义2. 类构造函数2.1. 实例化2.1.1 实例化流程2.1.2 带参实例化2.1.3 执行构造函数返回的两种对象2.1.4 类构造函数和普通构造函数的区别 2.2 把类当成特殊函数2.2.1 辨别是不是函数&#xff0c;使用 typeof2.2.2 辨别是不是函数&#xff0c;是否有prototype2…

学习篇 | Ollama 安装、运行大模型(CPU 实操版)

1. 操作步骤 1.1 安装 # 通过 homebrew 安装 brew install ollama1.2 验证&#xff08;可跳过&#xff09; # 输出命令使用提示则安装成功 ollama --help1.3 启动服务端 # 启动 ollama 服务&#xff08;默认在 11434 端口&#xff0c;模型文件在 ~/.ollama&#xff09; oll…

内核是如何接收网络包的

1、数据如何从网卡到网络协议栈 1.1内核收包的过程 1、数据帧从外部网络到达网卡 2、网卡把数据帧从自己的缓存DMA(拷贝到)和内核共有的RingBuffer上 3、网卡发出硬中断通知CPU 4、CPU响应硬中断&#xff0c;简单处理后发出软中断 5、k’softirqd线程处理软中断&#xff0c;调…