在git中,有两种打补丁的方式,一种是diff文件,生成的是unix标准补丁,另一种是patch文件,生成的是git专用补丁。

  • diff只会生成文件的改动信息,不会记载commit信息,多个commit能够合成一个diff文件
  • patch不但会记载文件改动信息,还会记载commit信息,例如commiter,commit date等,每个commit都会单独生成一个patch文件(由于里面包括commit信息)

diff 文件

diff --git a/a.txt b/a.txt                                                                                                                                                                                  
index 52295a4..469cdef 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,3 @@
 wo shi lightingsui
+
+wo yao shengcheng diff wenjian

patch文件

From 275803519accd2b4e89e20803ccc1814b8154c18 Mon Sep 17 00:00:00 2001
From: coolsui <coolsui@126.com>
Date: Thu, 24 Feb 2022 10:46:57 +0800
Subject: [PATCH] edit diff file
Signed-off-by: coolsui <coolsui@126.com>
---
 a.txt    | 2 ++
 sui.diff | 0
 2 files changed, 2 insertions(+)
 create mode 100644 sui.diff
diff --git a/a.txt b/a.txt
index 52295a4..469cdef 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,3 @@                                                                                                                                                                                               
 wo shi lightingsui
+
+wo yao shengcheng diff wenjian
diff --git a/sui.diff b/sui.diff
new file mode 100644
index 0000000..e69de29
-- 
2.17.1

生成patch

现在有三次commit,如下

commit c3c74a0c4a1237a0f0f80b33c4d17dd13538789d (HEAD -> sui)
Author: coolsui <coolsui@126.com>
Date:   Thu Feb 24 15:08:07 2022 +0800
    switch sui branch and edit a.txt
diff --git a/a.txt b/a.txt
index 469cdef..7d1ad46 100644
--- a/a.txt
+++ b/a.txt
@@ -1,3 +1,5 @@
 wo shi lightingsui
 wo yao shengcheng diff wenjian
+
+wo switch sui branch
commit 8472d9ba2fbb57ea8f2fd84290883ff55ba2a7a6
Author: coolsui <coolsui@126.com>
Date:   Thu Feb 24 11:09:50 2022 +0800
    edit a.txt
    Signed-off-by: coolsui <coolsui@126.com>
diff --git a/a.txt b/a.txt
index 52295a4..469cdef 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,3 @@
 wo shi lightingsui
+
+wo yao shengcheng diff wenjian
commit d3d623ff40dcfc2ef07c2499f2d20a05b6c16a8a
Author: coolsui <coolsui@126.com>
Date:   Thu Feb 24 10:44:21 2022 +0800
    add a.txt
    Signed-off-by: coolsui <coolsui@126.com>
diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..52295a4
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+wo shi lightingsui

生成diff补丁

指令格局: git diff sha1 sha2 > diffname

对上面的c3c74a0c4a1237a0f0f80b33c4d17dd13538789d8472d9ba2fbb57ea8f2fd84290883ff55ba2a7a6生成diff文件

git diff d3d623ff40dcfc2ef07c2499f2d20a05b6c16a8a c3c74a0c4a1237a0f0f80b33c4d17dd13538789d > 0001.diff
diff --git a/a.txt b/a.txt                                                                                                                                                                                  
index 52295a4..7d1ad46 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,5 @@
 wo shi lightingsui
+
+wo yao shengcheng diff wenjian
+
+wo switch sui branch

sha1为左区间的commit,sha2为右区间的commit,diff文件的规模(sha1, sha2]

生成patch补丁

对上面 c3c74a0c4a1237a0f0f80b33c4d17dd13538789d 生成 patch

指令格局:git format-patch sha -n

n的意义是对指定的 sha 表示的 commit 向前打 n 个commit(包括当时commit)的patch,为1时仅对当时 sha 表示的 commit 打 patch

sui@home:~/me/tmp/test$ git format-patch c3c74a0c4a1237a0f0f80b33c4d17dd13538789d -1
0001-switch-sui-branch-and-edit-a.txt.patch
From c3c74a0c4a1237a0f0f80b33c4d17dd13538789d Mon Sep 17 00:00:00 2001
From: coolsui <coolsui@126.com>
Date: Thu, 24 Feb 2022 15:08:07 +0800
Subject: [PATCH] switch sui branch and edit a.txt
---
 a.txt | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/a.txt b/a.txt
index 469cdef..7d1ad46 100644
--- a/a.txt
+++ b/a.txt
@@ -1,3 +1,5 @@
 wo shi lightingsui
 wo yao shengcheng diff wenjian
+
+wo switch sui branch
-- 
2.17.1

patch 文件不但生成了 diff 信息,还生成了 commit 信息。

当n 指定的数大于1时,会生成多个patch文件,每个commit生成一个文件

sui@home:~/me/tmp/test$ git format-patch c3c74a0c4a1237a0f0f80b33c4d17dd13538789d -2
0001-edit-a.txt.patch
0002-switch-sui-branch-and-edit-a.txt.patch

文件命名格局为: patch自增编号-commit title.txt.patch

运用patch

无论是patch还是diff文件,都能够被运用,例如代码转移操作

git apply

指令格局: git apply filename

无抵触合入

# --check 进行合入预检查,无任何输出代表检查通过
sui@home:~/me/tmp/test$ git apply --check 0001.diff
# 运用diff
sui@home:~/me/tmp/test$ git apply 0001.diff
# 无任何输出证明合入diff代码完成
sui@home:~/me/tmp/test$ 

运用apply运用diff文件或者patch文件并不会主动commit,能够运用git status检查(刚刚运用的diff文件中的修正现在状况为not staged)

sui@home:~/me/tmp/test$ git status
On branch sui
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:   a.txt

发生抵触

# 检查失利
sui@home:~/me/tmp/test$ git apply --check 0001.diff
error: patch failed: a.txt:1
error: a.txt: patch does not apply
# 合入失利
sui@home:~/me/tmp/test$ git apply 0001.diff
error: patch failed: a.txt:1
error: a.txt: patch does not apply

一旦repo中的文件和diff抵触,会提示无法合入,但不显现抵触的详细信息(只显现的发生抵触的位置在a.txt文件中)

能够运用git apply –reject filename,该指令会生成一个以发生抵触文件命名的以.rej结尾的文件,该文件显现了发生抵触的信息

sui@home:~/me/tmp/test$ git apply --reject  0001-edit-a.txt.patch
Checking patch a.txt...
error: while searching for:
wo shi lightingsui
error: patch failed: a.txt:1
Applying patch a.txt with 1 reject...
Rejected hunk #1.
sui@home:~/me/tmp/test$ ls
0001-edit-a.txt.patch  0002-switch-sui-branch-and-edit-a.txt.patch  a.txt  a.txt.rej
sui@home:~/me/tmp/test$ cat a.txt.rej
diff a/a.txt b/a.txt	(rejected hunks)
@@ -1 +1,3 @@
 wo shi lightingsui
+
+wo yao shengcheng diff wenjian

依据抵触文件的信息,进行处理,处理完成后删除去rej信息,commit即可

git am

指令格局: git am filename

无抵触合入

sui@home:~/me/tmp/test$ ls
0001-edit-a.txt.patch  0002-switch-sui-branch-and-edit-a.txt.patch  a.txt

# 批量合入 patch,代表两次 commit
sui@home:~/me/tmp/test$ git am *.patch
Applying: edit a.txt
Applying: switch sui branch and edit a.txt

由于patch文件携带commit信息,合入后不需要手动commit,会直接commit

sui@home:~/me/tmp/test$ git log
commit e0c28f3d46940580cb42cc981f13327969169a1b (HEAD -> sui)
Author: coolsui <coolsui@126.com>
Date:   Thu Feb 24 15:08:07 2022 +0800
    switch sui branch and edit a.txt
commit 3ff2070a73b5ade9262f5bace7ee2ae373c048b5
Author: coolsui <coolsui@126.com>
Date:   Thu Feb 24 11:09:50 2022 +0800
    edit a.txt
    Signed-off-by: coolsui <coolsui@126.com>
commit d3d623ff40dcfc2ef07c2499f2d20a05b6c16a8a
Author: coolsui <coolsui@126.com>
Date:   Thu Feb 24 10:44:21 2022 +0800
    add a.txt
    Signed-off-by: coolsui <coolsui@126.com>

发生抵触

sui@home:~/me/tmp/test$ git am *.patch
Applying: edit a.txt
error: a.txt: does not match index
Patch failed at 0001 edit a.txt
Use 'git am --show-current-patch' to see the failed 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".

发生抵触后,供给三个指令用来处理抵触

# 处理完抵触后(需运用git add指令), 履行该指令,持续合入操作
git am --continue
# 越过抵触
git am --skip
# 终止合入,恢复到运用该path之前的状况
git am --abort

apply与am区别

  1. git apply既能够合入git diff文件又能够合入git format-patch文件,而git am只能合入git format-patch文件
  2. git apply不会主动commit,而git am会主动commit