repo的patch转换成git am能打的patch

2024-08-21 08:04
文章标签 转换成 git repo patch

本文主要是介绍repo的patch转换成git am能打的patch,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

安卓sdk项目小的几十G,大的上百G,有的人会把sdk分成许多个小的git然后统一用repo来管理,还有的人会选择把sdk放在一个git中管理. 那么repo中修改后生成的patch是无法直接给git用的,因为路径不一样,patch内容也不相符
比如repo中device子目录是一个git,那么它生成的patch放到另一个git项目中只能cd到device路径,然后再用patch指令打,无法用git am xx.patch来打. 两边同步代码会很麻烦.
需要用脚本进行一个转换.

repo生成manifest快照

repo比如要生成0801到0805之间的修改的patch
8月1号用如下指令生成快照
./repo sync
./repo manifest -r -o manifest_0801.xml

中间做过修改.

8月5号再生成快照
./repo sync
./repo manifest -r -o manifest_0805.xml
得有两个快照, 才能生成这两个快照之间的diff提交.
生成快照后,接下来用脚本来生成两个快照间的修改的patch

生成repo快照间的提交的patch并转换成git am的patch

# 作者帅得不敢出门
# -*- coding: utf-8 -*-import sys
import os
import re
import subprocessdef do_popen(cmd):#popenprocess = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)stdout, stderr = process.communicate()return stdout.decode('utf-8')def auto_detect_manifests():"""遍历repo项目根目录,找到两个快照,快照以.xml结尾"""manifests = []for item in os.listdir('./'):if item.startswith('manifest') and item.endswith('.xml'):manifests.append(item)if len(manifests) != 2:print('Error:the number of manifest_xx.xml files are not equal to 2, abort!')sys.exit(1)manifests.sort()print(manifests)return manifestsdef get_diffmanifests():"""查看两个repo快照间的差异, 得到类似如下changed projects :bootable/bootloader/lk changed from e5f360f35a6d3848475ba4920f40c1609b1348b0 to ca0100b2da6ca7831348cb5fcfe8d23c529e8a57[+] ca0100b2 edit 1device/sprd/sepolicy changed from f15d0189283f767bd315f0900a59256323c071c2 to 64c586a362cb19a290280e79b2e20e8aab7d94cc[+] 64c586a hellokernel/msm-3.18 changed from f36f37a42a94fe78d5d7cbe2e8a4ab6477de74ab to 6b372c76fc0874d19822d978ad557a4aeec0ebee[+] 6b372c76fc08 word"""manifests = auto_detect_manifests()cmd = './repo diffmanifests ' + manifests[0] + ' ' + manifests[1]print(cmd)return do_popen(cmd)def get_diff_git_log():"""得到两个repo快照间的git修改的log[{'path': 'bootable/bootloader/lk', 'from': 'e5f360f35a6d3848475ba4920f40c1609b1348b0', 'to': 'ca0100b2da6ca7831348cb5fcfe8d23c529e8a57'}, {'path': 'device/sprd/sepolicy', 'from': 'f15d0189283f767bd315f0900a59256323c071c2', 'to': '64c586a362cb19a290280e79b2e20e8aab7d94cc'}, {'path': 'kernel/msm-3.18', 'from': 'f36f37a42a94fe78d5d7cbe2e8a4ab6477de74ab', 'to': '6b372c76fc0874d19822d978ad557a4aeec0ebee'}]"""data = get_diffmanifests()print(data)# 只保留\t开头的有效行line = [ x for x in data.split('\n') if x.startswith('\t')]ret = []for i in range(len(line)):if i % 2 == 0:#print(line[i])log = line[i].split()ret.append({'path':log[0], 'from':log[3], 'to':log[5]})#print(ret)return retdef get_format_patch(log, outdir):try:do_popen('rm ./*.patch ')except Exception as e:print('')# 生成从from开始的提交的git patch,生成的git是在子目录中生成的,所以需要在patch内容中的文件路径添加父目录do_popen('git format-patch ' + log['from'])for file in os.listdir('./'):if file.endswith('.patch'):print(file)with open(file, 'r') as fp:new_lines = []lines = fp.readlines()fp.close()for line in lines:#查找文件路径,并在前面拼接上目录, 把repo补丁转换成可以直接在git上打的patchif line.startswith('diff --git') or line.startswith('--- ') or line.startswith('+++ '):#print(line)new_line = re.sub(' a/', ' a/' + log['path'] + '/', line)new_line = re.sub(' b/', ' b/' + log['path'] + '/', new_line)#print(new_line)new_lines.append(new_line)else:new_lines.append(line)patch_name = os.path.join(outdir, file)with open(patch_name, 'w') as new_fp:print(patch_name)new_fp.writelines(new_lines)new_fp.close()try:do_popen('rm ./*.patch ')except Exception as e:print('')if __name__ == '__main__':"""通过repo获取到两个时间段的提交git log, 再通过git log获取patch"""# 生成的patch放在当前目录的patchs中patch_dir = os.path.join(os.getcwd(), 'patchs')if not os.path.exists(patch_dir):os.mkdir(patch_dir)else:try:# 先删除旧的patchdo_popen('rm ' + patch_dir + './*.patch ')except Exception as e:print('')#得到两个repo快照间的git修改的loglogs = get_diff_git_log()for log in logs:# 遍历git log进入到实际的子git目录中生成patchold_dir = os.getcwd()os.chdir(log['path'])print(log['path'])# 把所有的子git中的修改制作成patch放到patchs目录下get_format_patch(log, patch_dir)os.chdir(old_dir)

作者:帅得不敢出门 csdn原创谢绝转载

这篇关于repo的patch转换成git am能打的patch的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092584

相关文章

bat脚本启动git bash窗口,并执行命令方式

《bat脚本启动gitbash窗口,并执行命令方式》本文介绍了如何在Windows服务器上使用cmd启动jar包时出现乱码的问题,并提供了解决方法——使用GitBash窗口启动并设置编码,通过编写s... 目录一、简介二、使用说明2.1 start.BAT脚本2.2 参数说明2.3 效果总结一、简介某些情

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

多重背包转换成0-1背包

http://acm.hdu.edu.cn/showproblem.php?pid=2191 多重背包特点: 一种物品有C个(既不是固定的1个,也不是无数个) 优化的方法: 运用神奇的二进制,进行物品拆分,转化成01背包 物品拆分,把13个相同的物品分成4组(1,2,4,6) 用这4组可以组成任意一个1~13之间的数! 原理:一个数总可以用2^

git ssh key相关

step1、进入.ssh文件夹   (windows下 下载git客户端)   cd ~/.ssh(windows mkdir ~/.ssh) step2、配置name和email git config --global user.name "你的名称"git config --global user.email "你的邮箱" step3、生成key ssh-keygen

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个

Git 的特点—— Git 学习笔记 02

文章目录 Git 简史Git 的特点直接记录快照,而非差异比较近乎所有操作都是本地执行保证完整性一般只添加数据 参考资料 Git 简史 众所周知,Linux 内核开源项目有着为数众多的参与者。这么多人在世界各地为 Linux 编写代码,那Linux 的代码是如何管理的呢?事实是在 2002 年以前,世界各地的开发者把源代码通过 diff 的方式发给 Linus,然后由 Linus