Git常用命令format-patch

这篇具有很好参考价值的文章主要介绍了Git常用命令format-patch。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Git常用命令format-patch

我们在日常的开发中,需要将自己的改动给到其他同事时,经常需要将改动打补丁 (patch) 后进行处理。

git format-patch 是一种帮助开发人员从其 git 提交创建补丁的命令。这个命令很有用,可以用于各种原因,如代

码审查、在分支之间共享代码更改以及向邮件列表提交补丁。对于 git format-patch 的补丁,可以使用 git am 命

令进行打入。

本文我们将详细解释 git format-patch 和 git am 命令以及如何有效使用它。

1、format-patch基本用法

$ git format-patch filename.patch

git format-patch 命令可以输出多种格式的补丁。默认情况下,它会以 Git 邮箱格式输出补丁。但是,您可以使用

以下选项来输出其他格式的补丁:

  • --stdout 选项将补丁输出到标准输出,而不是将其写入文件。当您想将补丁传输到其他 Git 命令或工具时,

    此选项非常有用。

  • --mbox 选项以 mbox 格式输出补丁。当通过电子邮件发送补丁时,此格式非常有用。

  • --raw 选项以原始格式输出补丁。当您想向非 Git 存储库应用补丁时,此格式非常有用。

  • --numbered 选项按顺序编号补丁。当您想生成多个补丁并保持它们的特定顺序时,此选项非常有用。

git format-patch 命令可以通过指定提交范围或逐个指定一个或多个提交来使用。

format-patch可以基于分支进行打包,也可以基于上几次更新内容打包。

下面将演示其几中用法。

# 分支的提交记录
$ git log --oneline
b9709d6 (HEAD -> branch_a, origin/branch_a) branch_a | update a.txt | add new.txt
105370e add f.txt
46409d9 add e.txt
082352c add d.txt
d8f4266 add c.txt
a5e5961 add b.txt
4db21f4 add a.txt
# 打包最近的一个patch
$ git format-patch HEAD^
0001-branch_a-update-a.txt-add-new.txt.patch
# 打包最近的两个patch
$ git format-patch HEAD^^
0001-add-f.txt.patch
0002-branch_a-update-a.txt-add-new.txt.patch
# 打包最近的三个patch
$ git format-patch HEAD^^^
0001-add-e.txt.patch
0002-add-f.txt.patch
0003-branch_a-update-a.txt-add-new.txt.patch
# 有几个^就打包几个patch的内容或
# 可以使用git format-patch -n,两者是等价的
# 打包最近的一个patch
$ git format-patch -1
0001-branch_a-update-a.txt-add-new.txt.patch
# 打包最近的两个patch
$ git format-patch -2
0001-add-f.txt.patch
0002-branch_a-update-a.txt-add-new.txt.patch
# 打包版本n1与n2之间的patch
$ git format-patch -n1 -n2
# 可以打包版本2,3的patch
# 但是测试会把最近4个包都打包出来
$ git format-patch -1 -4
0001-add-d.txt.patch
0002-add-e.txt.patch
0003-add-f.txt.patch
0004-branch_a-update-a.txt-add-new.txt.patch

# 测试会把最近3个包都打包出来
$ git format-patch -1 -3
0001-add-e.txt.patch
0002-add-f.txt.patch
0003-branch_a-update-a.txt-add-new.txt.patch

# 测试会把最近2个包都打包出来
$ git format-patch -1 -2
0001-add-f.txt.patch
0002-branch_a-update-a.txt-add-new.txt.patch

# 测试会把最近1个包都打包出来
$ git format-patch -1 -1
0001-branch_a-update-a.txt-add-new.txt.patch
# 某次提交以后的所有patch
# 082352c add d.txt
# 不包含此次提交
$ git format-patch -s 082352c
# 等价
$ git format-patch 082352c
0001-add-e.txt.patch
0002-add-f.txt.patch
0003-branch_a-update-a.txt-add-new.txt.patch
# 某次提交之前的几次提交
# 包含本次提交
$ git format-patch -2 082352c
0001-add-c.txt.patch
0002-add-d.txt.patch
# 某两次提交之间的所有patch
# 不包含start的提交
# 46409d9 add e.txt
# 082352c add d.txt
# d8f4266 add c.txt
# a5e5961 add b.txt
$ git format-patch a5e5961..46409d9
0001-add-c.txt.patch
0002-add-d.txt.patch
0003-add-e.txt.patch
# 将所有patch输出到一个指定位置的指定文件
$ git format-patch commit --stdout > filename.patch
$ git format-patch d8f4266 --stdout > d8f4266.patch
# 经常使用的格式
# patch_name的格式类似于0001-bdbfc4ca3.patch
$ git format-patch -1 -k commit --stdout > dir_name/patch_name
$ git format-patch -1 -k d8f4266 --stdout> /tmp/0001-d8f4266.patch
# 当前分支所有超前branch_a的提交
$ git log --oneline
b1786d3 (HEAD -> branch_b, origin/branch_b) branch_b | update a.txt | add new.txt
b9709d6 (origin/branch_a) branch_a | update a.txt | add new.txt
105370e add f.txt
46409d9 add e.txt
082352c add d.txt
d8f4266 add c.txt
a5e5961 add b.txt
4db21f4 add a.txt

# 当前分支比较大
$ git format-patch -M origin/branch_a
0001-branch_b-update-a.txt-add-new.txt.patch
# 从origin到指定提交的所有patch
$ git format-patch -s --root origin
0001-add-a.txt.patch
0002-add-b.txt.patch
0003-add-c.txt.patch
0004-add-d.txt.patch
0005-add-e.txt.patch
0006-add-f.txt.patch
0007-branch_a-update-a.txt-add-new.txt.patch
0008-branch_b-update-a.txt-add-new.txt.patch
0009-branch_c-update-a.txt-delete-e.txt.patch
0010-develop-add-test.txt.patch
# 要为最后两个提交生成补丁
$ git format-patch HEAD~2..HEAD
0001-branch_a-update-a.txt-add-new.txt.patch
0002-branch_b-update-a.txt-add-new.txt.patch
# 当前分支和某个分支差异的patch
# 当前分支比价大
$ git format-patch branch_a
0001-branch_b-update-a.txt-add-new.txt.patch

2、git am基本用法

在使用 git am 前,首先要使用 git am –abort,用来放弃以前的 am 信息,否则可能会遇到这样的错误:

.git/rebase-apply still exists but mbox given

基本语法:

# 打入patch
$ git am filename.patch
# 等价于
$ git am -k filename.patch

3、应用patch

3.1 检查patch能否正常应用

# 不应用修补程序,而是输出diffstat作为输入
$ git apply --stat filename.patch
# 不应用修补程序,而是查看修补程序是否适用
$ git apply --check filename.patch

3.2 应用patch

git apply 命令通过修改现有文件或创建新文件来将补丁应用到代码库中。

$ git apply filename.patch

git apply 命令还可以与各种选项一起使用,例如 --check 以检查是否能干净地应用补丁,--reject以创建带有

拒绝更改的补丁文件,以及 --index 以将更改添加到Git索引。

git am:

$ git am filename.patch
# 一次打入多个文件
$ git am *.patch

4、git format-patch使用案例

4.1 分支现有的情况

touch a.txt
git add a.txt
git commit -m "add a.txt"

touch b.txt
git add b.txt
git commit -m "add b.txt"

touch c.txt
git add c.txt
git commit -m "add c.txt"

touch d.txt
git add d.txt
git commit -m "add d.txt"

touch e.txt
git add e.txt
git commit -m "add e.txt"

touch f.txt
git add f.txt
git commit -m "add f.txt"

$ ls
a.txt  b.txt  c.txt  d.txt  e.txt  f.txt

$ git log --oneline
3d47274 (HEAD -> master) add f.txt
f21670a add e.txt
3be00b5 add d.txt
8480613 add c.txt
054694f add b.txt
6cd2b56 add a.txt

$ git show 3d47274
commit 3d472749b02447f9e295bc924c95044a40a8ab42 (HEAD -> master)
Author: zsx242030 <2420309401@qq.com>
Date:   Mon May 22 21:34:28 2023 +0800

    add f.txt

diff --git a/f.txt b/f.txt
new file mode 100644
index 0000000..e69de29

4.2 打包最后一次提交

$ git format-patch -1 -k 3d47274
0001-add-f.txt.patch

$ cat 0001-add-f.txt.patch
From 3d472749b02447f9e295bc924c95044a40a8ab42 Mon Sep 17 00:00:00 2001
From: zsx242030 <2420309401@qq.com>
Date: Mon, 22 May 2023 21:34:28 +0800
Subject: add f.txt

---
 f.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 f.txt

diff --git a/f.txt b/f.txt
new file mode 100644
index 0000000..e69de29
--
2.14.1.windows.1

如果有额外信息需要补充,但又不想放在提交消息中说明,可以编辑这些补丁文件,在第一个 --- 行之前添加说

明,但不要修改下面的补丁正文。这样,其它开发者能阅读,但在采纳补丁时不会将此合并进来。

4.3 恢复提交到上一次提交

$ git reset --hard HEAD^
HEAD is now at f21670a add e.txt

$ git log --oneline
f21670a (HEAD -> master) add e.txt
3be00b5 add d.txt
8480613 add c.txt
054694f add b.txt
6cd2b56 add a.txt

4.4 检查patch能否正常应用

$ git apply --stat 0001-add-f.txt.patch
 f.txt |    0
 1 file changed, 0 insertions(+), 0 deletions(-)
$ git apply --check 0001-add-f.txt.patch

4.5 应用patch

4.5.1 git am
$ git am 0001-add-f.txt.patch
Applying: add f.txt

$ git log --oneline
b8eafce (HEAD -> master) add f.txt
f21670a add e.txt
3be00b5 add d.txt
8480613 add c.txt
054694f add b.txt
6cd2b56 add a.txt
4.5.2 git apply
# git apply执行之后需要自己提交文件
$ git apply 0001-add-f.txt.patch

$ ls
a.txt  b.txt  c.txt  d.txt  e.txt  f.txt

$ git log --oneline
b8eafce (HEAD -> master) add f.txt
f21670a add e.txt
3be00b5 add d.txt
8480613 add c.txt
054694f add b.txt
6cd2b56 add a.txt

$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        0001-add-f.txt.patch
        f.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add f.txt

$ git commit -m "add f.txt"
[master de26d5b] add f.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 f.txt

$ git log --oneline
de26d5b (HEAD -> master) add f.txt
f21670a add e.txt
3be00b5 add d.txt
8480613 add c.txt
054694f add b.txt
6cd2b56 add a.txt

如果只是想生效改动而不需要直接提交代码,可以使用 git apply 代替 git am。

5、git am时有冲突

5.1 分支情况

# master
touch a.txt
git add a.txt
git commit -m "add a.txt"

touch b.txt
git add b.txt
git commit -m "add b.txt"

$ git log --oneline
4ac5e82 (HEAD -> master) add b.txt
ce93e86 add a.txt
# featurea
$ cat >> a.txt << EOF
11
aa
22
bb
33
cc
EOF

git add .
git commit -m "update a.txt"

$ git log --oneline
11ea22f (HEAD -> featurea) update a.txt
4ac5e82 (master) add b.txt
ce93e86 add a.txt
# featureb
$ cat >> a.txt << EOF
aa
11
bb
22
cc
33
EOF

git add a.txt
git commit -m "update a.txt"

$ git log --oneline
6c9e62d (HEAD -> featureb) update a.txt
4ac5e82 (master) add b.txt
ce93e86 add a.txt

featurea 分支和 featureb 分支的内容是有冲突的,featurea 先开发完了,然后 featureb 又进行了修改,会导致

a.txt 文件冲突。

5.2 featurea打最后一次的patch

# featureb
$ git format-patch -1
0001-update-a.txt.patch

5.3 featureb打入patch

# featurea
$ git am 0001-update-a.txt.patch
error: patch failed: a.txt:0
error: a.txt: patch does not apply
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Applying: update a.txt
Patch failed at 0001 update a.txt
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

由于两个分支都同时操作了某个文件,导致冲突,这种情况下可以使用下面的方法解决冲突:

1、执行命令 git apply --reject finame.patch 自动合入 patch 中不冲突的代码改动,同时保留冲突的部分。这些

存在冲突的改动内容会被单独存储到目标源文件的相应目录下,以后缀为 .rej 的文件进行保存。

$ git apply --reject 0001-update-a.txt.patch
Checking patch a.txt...
error: while searching for:

error: patch failed: a.txt:0
Applying patch a.txt with 1 reject...
Rejected hunk #1.

会生成一个 a.txt.rej 文件:

$ cat a.txt.rej
diff a/a.txt b/a.txt    (rejected hunks)
@@ -0,0 +1,6 @@
+aa
+11
+bb
+22
+cc
+33

2、依据上面生成的 *.rej 文件内容逐个手动解决冲突,然后删除这些 *.rej 文件。

我们解决 a.txt 文件中的冲突,将内容替换为两者的合并:

11
aa
aa
11
22
bb
bb
22
33
cc
cc
33

然后删除 a.txt.rej 文件:

$ rm -rf a.txt.rej

完成这一步骤的操作后,我们就可以继续执行 git am 的过程了。

$ git am 0001-update-a.txt.patch
fatal: previous rebase directory .git/rebase-apply still exists but mbox given.

# 如果报上面的错误
# 解决方法

$ git am --abort

# 继续执行
$ git am 0001-update-a.txt.patch
error: a.txt: does not match index
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Applying: update a.txt
Patch failed at 0001 update a.txt
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

3、执行完上述命令之后执行 git status 查看当前改动过的以及新增的文件,确保没有多添加或少添加文件。

$ git status
On branch featurea
You are in the middle of an am session.
  (fix conflicts and then run "git am --continue")
  (use "git am --skip" to skip this patch)
  (use "git am --abort" to restore the original branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   a.txt

4、执行命令 git add 添加所有有改动的文件,将文件都添加到暂存区。

$ git add a.txt

5、执行命令 git am --continue 或者是 git am --resolved 继续被中断的 patch 合入操作。合入完成后,会有提示

信息输出。

$ git am --continue
Applying: update a.txt

6、执行命令 git log 确认合入状态。

$ git log --oneline
1add6d0 (HEAD -> featurea) update a.txt
11ea22f update a.txt
4ac5e82 (master) add b.txt
ce93e86 add a.txt

7、至此,带有冲突代码的 patch 合入就操作完成了。如果要修改 commit 信息,执行 git commit --amend 命令

即可。

$ git commit --amend -m "second update a.txt"

$ git log --oneline
3c27164 (HEAD -> featurea) second update a.txt
11ea22f update a.txt
4ac5e82 (master) add b.txt
ce93e86 add a.txt

5.4 冲突解决的另一种方式

如果想让 Git 更智能地处理冲突,可以用 -3 选项进行三方合并。如果当前分支未包含该补丁的基础代码或其祖

先,那么三方合并就会失败,所以该选项默认为关闭状态。一般来说,如果该补丁是基于某个公开的提交制作而成

的话,你总是可以通过同步来获取这个共同祖先,所以用三方合并选项可以解决很多麻烦。

还是以上面的冲突为例进行演示:

# featurea
$ git am -3 0001-update-a.txt.patch
Applying: update a.txt
error: Failed to merge in the changes.
Using index info to reconstruct a base tree...
M       a.txt
Falling back to patching base and 3-way merge...
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Patch failed at 0001 update a.txt
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
$ cat a.txt
<<<<<<< HEAD
11
aa
22
bb
33
cc
=======
aa
11
bb
22
cc
33
>>>>>>> update a.txt
# 解决冲突
$ cat a.txt
11
aa
aa
11
22
bb
bb
22
33
cc
cc
33
$ git add a.txt

$ git am --continue
Applying: update a.txt

$ git commit --amend -m "second update a.txt"

$ git log --oneline
bf7a56b (HEAD -> featurea) second update a.txt
b7622ab update a.txt
2dc23a3 (master) add b.txt
b568674 add a.txt

对于一次应用多个补丁时所用的 mbox 格式文件,可以用 am 命令的交互模式选项 -i,这样就会在打每个补丁前

停住,询问该如何操作:

$ git am -3 -i 0001-update-a.txt.patch
Commit Body is:
--------------------------
update a.txt
--------------------------
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: v
---
 a.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/a.txt b/a.txt
index e69de29..c1ba934 100644
--- a/a.txt
+++ b/a.txt
@@ -0,0 +1,6 @@
+aa
+11
+bb
+22
+cc
+33
--
2.14.1.windows.1

Commit Body is:
--------------------------
update a.txt
--------------------------
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: n

在多个补丁要打的情况下,这是个非常好的办法,一方面可以预览下补丁内容,同时也可以有选择性的接纳或跳过

某些补丁。文章来源地址https://www.toymoban.com/news/detail-559424.html

到了这里,关于Git常用命令format-patch的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Git】git常用命令集合

      Git是现代软件开发不可或缺的版本控制工具,它可以追踪文件的变化、协同开发以及管理代码版本。掌握Git的常用命令对于开发人员来说至关重要。本文将为你介绍一些Git常用命令,帮助你轻松驾驭版本控制。   详细介绍了Git的常用命令,涵盖了版本管理、分支操作、

    2023年04月08日
    浏览(68)
  • git快速入门!!! git的常用命令!!!

    Git 是一个开源的分布式版本控制系统,有很多实用的命令可以帮助我们更高效地管理项目和代码。以下是一些常用的 Git 命令及其使用方法和示例: 1. 初始化一个新的 Git 仓库 这个命令会在当前目录下创建一个新的 Git 仓库。 2. 添加文件到暂存区 这个命令会把指定的文件添

    2024年02月05日
    浏览(56)
  • git 常用命令之 git checkout

    大家好,我是 17。 git checkout 是 git 中最重要最常用的命令之一,本文为大家详细解说一下。 checkout 的用途之一是恢复工作区。 checkout . 表示恢复工作区的所有更改,未跟踪的文件不会有变化。 恢复工作区的所有文件风险比较大,会丢失所有工作区的修改,一定要慎用 中间加

    2023年04月13日
    浏览(84)
  • 【Git】git环境如何搭建与其常用命令

    搭建 Git 环境: 安装 Git 客户端:根据操作系统选择对应的版本进行下载安装,下载地址:https://git-scm.com/downloads。 配置 Git 用户名和邮箱:打开 Git Bash(Windows 系统)或终端(Mac、Linux 系统),输入以下命令进行配置。 常用 Git 命令: 初始化 Git 仓库:在项目目录下通过以下

    2023年04月25日
    浏览(53)
  • Git系列讲解(五):Git常用命令整理

    Git系列的前几篇文章针对基础知识进行了详细讲解,但是Git还包含很多其他命令,就不每个都展开细讲了,本篇文章整理了一些2.0+版本的常用Git命令,以供备忘。 1.1 git clone url 本地路径 克隆远程版本库到本地所指定的路径中,包括代码,分支和版本的提交记录等; 若后面不

    2024年02月04日
    浏览(43)
  • 【git】工作场景中常用的git命令

    工作场景中常用的git命令,记录下来方便调取 一般与他人合作,至少你提交的名字得被人熟知或者遵循规范,因此需要更改名字和邮箱 全局修改 只对本项目的修改 有时候你想使用简略的命令如直接 git push 而不指定远程分支,则需要设置一个远程分支作为你的上游分支 我们

    2024年02月11日
    浏览(40)
  • git常用命令(git github ssh)

    被” “和\\\"[ ]“包含起来的内容表示用户自己选定的参数。但” “是要求用户必须输入的,而”[ ]\\\"表示用户可以根据自己的需要选择输入。 比如git reset的语法是这样的: 其中commitid指的是commit id,可以理解为每一提交到本地仓库之后该仓库状态的ID,利用这个ID我们可以快速

    2024年02月03日
    浏览(52)
  • git : 常用命令合集

    git 基本组成框架:Workspace、Stage、Repository、Remote Workspace :开发者工作区,当前写代码的目录 Stage :暂存区 / 缓存区 Repository :本地仓库,本地所有的提交都会保存在这里,git 会保存好每一个历史版本 Remote :远程仓库,服务器仓库(github,gitee...) 生成 SSH 公钥和私钥,公

    2023年04月11日
    浏览(66)
  • Git常用命令submodule

    当程序比较大参与开发人员较多时,代码管理就复杂起来。代码如果全员可见,可以创建 share 分支维护共用代 码,可以创建 core 分支维护核心算法代码,各进程分别占一个分支,定期同步 share 和 core 分支。代码如果不 能全员可见,可以仓库中包含子仓库,子仓库管理模块代

    2024年02月08日
    浏览(45)
  • Git常用命令rebase

    rebase 会把你当前分支的 commit 放到公共分支的最后面,所以叫变基,就好像你从公共分支又重新拉出来这个 分支一样。 例如如果你从 master 拉了个 feature 分支出来,然后你提交了几个 commit,这个时候刚好有人把他开发的东西 合并到 master 了,这个时候 master 就比你拉分支的时

    2024年02月16日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包