背景介绍
我们在日常的开发中, 涉及对第三方源码的修改或在需要将自己的改动给到其他同事时,经常需要将改动打patch后进行处理. 这时候我们常直接使用diff命令生成patch文件, 然后通过patch进行打对应的patch文件. 详细的使用请看这篇博客中的说明: Linux下生成patch和打patch
然后这种直接使用diff和patch的方式,并不是最优解. 这里会更加建议使用git提供的format-patch 进行patch文件的生成以及通过am进行patch文件的打入. 接下来的示例代码会展示其更优的点
如何使用 git format-patch 和git am
使用git format-patch 生成patch文件
下面以往libchrome这一代码仓库进行文件修改,然后生成patch为例.
? libchrome git:(master) ? ls
Android.bp build BUILD.IGNORE crypto device libchrome_tools MODULE_LICENSE_BSD NOTICE soong testrunner.cc ui
base BUILD.gn components dbus ipc METADATA mojo OWNERS testing third_party
? libchrome git:(master) ?
如上所示, 时libchrome的一个仓库. 然后我修改了顶层目录中的文件Android.bp, 改动如下:
diff --git a/Android.bp b/Android.bp
index 45392653e..4874aaad0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -38,6 +38,7 @@ package {
// to attach the license to, and including a comment whether the files may be
// used in the current project.
// See: http://go/android-license-faq
+// git format-patch test
license {
name: "external_libchrome_license",
visibility: [":__subpackages__"],
(END)
然后将该改动提交, 操作如下:
? libchrome git:(master) ? git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: Android.bp
no changes added to commit (use "git add" and/or "git commit -a")
? libchrome git:(master) ? git add .
? libchrome git:(master) ? git commit -m "feat: test"
[master bad02e32d] feat: test
1 file changed, 1 insertion(+)
然后通过git log 查看对应提交的commit id
commit bad02e32d47a8ea82b2bcb02b5e8950f23f61623 (HEAD -> master)
Author: laixiaoqiang <laixiaoqiang@xxxx.com>
Date: Mon Nov 22 19:49:42 2021 +0800
feat: test
commit 06d255220dedb1f7058899536fd120bde5e6d904 (tag: android-s-v2-preview-1, origin/master, origin/android-s-v2-preview-1, origin/HEAD)
Merge: 121235bfa 902749c7e
Author: Paul Duffin <paulduffin@google.com>
Date: Wed Jul 14 23:25:04 2021 +0000
Stop using deprecated functionality for managing path deps am: 62d44c8c10 am: 902749c7e2
Original change: https://android-review.googlesource.com/c/platform/external/libchrome/+/1761028
Change-Id: Iffea5fa594c77bfae52c2f348a70d6c34dd77a8b
如上图可以得到commit bad02e32d47a8ea82b2bcb02b5e8950f23f61623为我们需要打包为patch的提交. 最后使用git format-patch 命令生成patch文件.
? libchrome git:(master) git format-patch bad02e32d47a8ea82b2bcb02b5e8950f23f61623 -1
0001-feat-test.patch
? libchrome git:(master) ? cat 0001-feat-test.patch
From bad02e32d47a8ea82b2bcb02b5e8950f23f61623 Mon Sep 17 00:00:00 2001
From: laixiaoqiang <laixiaoqiang@xiaomi.com>
Date: Mon, 22 Nov 2021 19:49:42 +0800
Subject: [PATCH] feat: test
---
Android.bp | 1 +
1 file changed, 1 insertion(+)
diff --git a/Android.bp b/Android.bp
index 45392653e..4874aaad0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -38,6 +38,7 @@ package {
// to attach the license to, and including a comment whether the files may be
// used in the current project.
// See: http://go/android-license-faq
+// git format-patch test
license {
name: "external_libchrome_license",
visibility: [":__subpackages__"],
--
2.17.1
如上所示有以下几点需要注意:
- 使用的命令:
git format-patch bad02e32d47a8ea82b2bcb02b5e8950f23f61623 -1
commit id后面跟着的参数-1 指的是当前仅是需要将bad02e32d47a8ea82b2bcb02b5e8950f23f61623这一commit生成patch文件.
- 通过 0001-feat-test.patch可以看出, format-patch生成的patch文件有一个有优点是在于记录修改者等git提交信息,以及文件的格式我们更加的熟悉.
那对于这种方式生从的patch文件我们该如何使用呢? ehh 那让我们先reset bad02e32d47a8ea82b2bcb02b5e8950f23f61623 这一提交,然后进行接下来的演示.
? libchrome git:(master) ? git reset --hard 06d255220dedb1f7058899536fd120bde5e6d904
HEAD is now at 06d255220 Stop using deprecated functionality for managing path deps am: 62d44c8c10 am: 902749c7e2
使用git am命令打对应的patch文件0001-feat-test.patch
? libchrome git:(master) ? git am 0001-feat-test.patch
Applying: feat: test
? libchrome git:(master) ?
然后通过git log 命令, 可以看到如下提交:
commit 01d340a508c16c4e262bb24c67f991a63db62df1 (HEAD -> master)
Author: laixiaoqiang <laixiaoqiang@xxx.com>
Date: Mon Nov 22 19:49:42 2021 +0800
feat: test
commit 06d255220dedb1f7058899536fd120bde5e6d904 (tag: android-s-v2-preview-1, origin/master, origin/android-s-v2-preview-1, origin/HEAD)
可以看出git am 直接将0001-feat-test.patch打入并自动生成提交. 如果只是想生效改动而不需要直接提交代码,可以使用git apply 替代.
? libchrome git:(master) ? git apply 0001-feat-test.patch
? libchrome git:(master) ? git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: Android.bp
补充说明
另外当需要将多个提交生成patch文件,可以使用如下命令, 例如: libchrom这一代码仓库, 需要将 88c7d5c272925d8f27366ed239a4f46ae00ceb16 f00850730180e5cb6c0b74e58ba9aaab17545b57 生成patch文件.
commit 88c7d5c272925d8f27366ed239a4f46ae00ceb16
Author: Inseob Kim <inseob@google.com>
Date: Mon Jun 14 12:57:12 2021 +0900
Add ramdisk_available to init_first_stage's deps
Bug: 187196593
Test: boot
Change-Id: I7436b8dd11ca747459d442b3d754c5367a9eb721
Merged-In: I7436b8dd11ca747459d442b3d754c5367a9eb721
commit f00850730180e5cb6c0b74e58ba9aaab17545b57
Merge: 39896b6f1 ab0b0fa5c
Author: Inseob Kim <inseob@google.com>
Date: Fri Jun 18 18:14:50 2021 +0000
Add ramdisk_available to init_first_stage's deps am: 35abebfab5 am: ab0b0fa5c5
Original change: https://android-review.googlesource.com/c/platform/external/libchrome/+/1736238
Change-Id: Ibd8746381ce4518a0195bc70e1cf35406ff3c2c7
commit ab0b0fa5c5b0ecfa6d7f60da3e7b153c4337d4c4
Merge: 6f365e25e 35abebfab
Author: Inseob Kim <inseob@google.com>
Date: Fri Jun 18 17:57:25 2021 +0000
Add ramdisk_available to init_first_stage's deps am: 35abebfab5
Original change: https://android-review.googlesource.com/c/platform/external/libchrome/+/1736238
Change-Id: I36a066ceb149a2f6ac00ee81ae8f7fd9742d505e
执行命令如下:
? libchrome git:(master) ? git format-patch ab0b0fa5c5b0ecfa6d7f60da3e7b153c4337d4c4..88c7d5c272925d8f27366ed239a4f46ae00ceb16
0001-Add-ramdisk_available-to-init_first_stage-s-deps.patch
? libchrome git:(master) ?
? libchrome git:(master) ? ls
0001-Add-ramdisk_available-to-init_first_stage-s-deps.patch Android.bp build BUILD.IGNORE crypto device libchrome_tools MODULE_LICENSE_BSD NOTICE soong testrunner.cc ui
0001-feat-test.patch base BUILD.gn components dbus ipc METADATA mojo OWNERS testing third_party
? libchrome git:(master) ?
可以看出执行该命令后生从了如下两个patch文件, 也就是该两个commit对应的patch.
0001-Add-ramdisk_available-to-init_first_stage-s-deps.patch
0001-feat-test.patch
ehh 这里是两个patch?? 该怎么一次性打入呢? 可以执行如下命令:
git am *.patch // *.patch 需要是patch文件的所在路径
最后需要补充说明的是,git format-patch/ git am 在平台适配时的代码移植时使用比较高效,另外需要注意与bundle/cherry-pick的差异.
|