背景

当我们修改了代码准备提交时,本地的改动可能包含了不能提交的调试语句,还可能需要拆分成多个细粒度的 pactch

本文将介绍如何使用 git add -p 来交互式选择代码片段,辅助整理出所需的 patch

官方介绍

先贴个帮助信息供参考

英文版本:

 -p, --patch
Interactively choose hunks of patch between the index and the work tree and add them to
the index. This gives the user a chance to review the difference before adding modified
contents to the index. This effectively runs add --interactive, but bypasses the initial command menu and
directly jumps to the patch subcommand. See “Interactive mode” for details.

中文版本:

-p, --patch
交互地在索引和工作树之间选择补丁块并将它们添加到索引中。这让用户有机会在将修改后的内容添加到索引之前查看差异。 这可以有效地运行 add --interactive,但是会绕过初始命令菜单,而直接跳转到 patch 子命令。有关详细信息,请参见`‘交互模式’'。

demo 视频版

以下文字版例子对应的视频演示

demo 文字版

我们造个例子来说明,假设我们本次完成了两个功能,fun1 和 fun2,希望分开提交。另外在修改过程中还引入了一些调试的打印,是不需要提交的。

代码的 diff 如下

 --git a/demo.c b/demo.c
index 0473c1a..76cfb22 100644
--- a/demo.c
+++ b/demo.c
@@ -1,16 +1,31 @@
#include <stdio.h> +void fun1()
+{
+ printf("before hello world\n");
+}
+
void demo()
{
;
} +void fun2()
+{
+ printf("after hello world\n");
+}
+
int main()
{
+ fun1();
printf("hello world\n");
+ printf("debug %s %d\n", __func__, __LINE__);
printf("hello world\n");
printf("hello world\n");
printf("hello world\n");
+ printf("debug %s %d\n", __func__, __LINE__);
printf("hello world\n");
+ fun2();
demo();
+ printf("debug %s %d\n", __func__, __LINE__);
}

此时直接 git add 会把整个文件的改动都加进来,不符合需求。

这正是 patch mode 发挥作用的地方,我们可以挑选一部分改动进行提交。

输入 git add -p 进入 patch mode , 此时 git 会自动将改动切分成多个片段,并展示第一个片段,提示你进行选择。

提示语句是 Stage this hunk [y,n,q,a,d,/,s,e,?]?

这些字母都是什么意思呢? 输入?回车,可以查看详细的帮助信息。

英文版本:

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

中文版本:

y - 暂存此区块
n - 不暂存此区块
q - 退出;不暂存包括此块在内的剩余的区块
a - 暂存此块与此文件后面所有的区块
d - 不暂存此块与此文件后面所有的 区块
g - 选择并跳转至一个区块
/ - 搜索与给定正则表达示匹配的区块
j - 暂不决定,转至下一个未决定的区块
J - 暂不决定,转至一个区块
k - 暂不决定,转至上一个未决定的区块
K - 暂不决定,转至上一个区块
s - 将当前的区块分割成多个较小的区块
e - 手动编辑当前的区块
? - 输出帮助

对于我们的例子,git第一次自动给出的hunk很大,可以先执行 s 分割下。分割后第一个区块就只包含增加的 fun1 函数了。

/* 太占篇幅,此处省略原始 hunk */
Stage this hunk [y,n,q,a,d,/,s,e,?]? s /* 询问我们对第一个片段的处理,我们觉得太大,按 s 要求分割 */
Split into 7 hunks. /* 可以看到,s 让 git 将原始片段进一步切分成了 7 个片段,接下来就是自动展示第一个片段 */
@@ -1,7 +1,12 @@
#include <stdio.h> +void fun1()
+{
+ printf("before hello world\n");
+}
+
void demo()
{
;
} Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? /* 询问我们对第一个片段的处理 */

输入 y 回车选中这个 fun1 的改动,git 就会自动展示下一个片段,继续询问我们。

这样对片段使用 yn,我们就可以只挑选出涉及 fun1 的改动,当我们确认后续没有 fun1 相关的改动时,就可以按 q 退出挑选了。

此时 git status 可以看到部分改动在暂存区中。

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage) modified: demo.c 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: demo.c

使用 git diff --cached 可以具体确认要提交的内容,是否符合我们的预期,只包含 fun1 的改动,不包含 fun2 和调试语句。

$ git diff --cached
diff --git a/demo.c b/demo.c
index 0473c1a..b9fd4d4 100644
--- a/demo.c
+++ b/demo.c
@@ -1,5 +1,10 @@
#include <stdio.h> +void fun1()
+{
+ printf("before hello world\n");
+}
+
void demo()
{
;
@@ -7,6 +12,7 @@ void demo() int main()
{
+ fun1();
printf("hello world\n");
printf("hello world\n");
printf("hello world\n");

确认无误就可以提交第一个patch, 即 fun1 的改动了。

git commit -m "fun1"

接下来继续使用 git add -p,配合s,y,'n'就可以进一步挑选出fun2的改动了。

如果要挑选的改动比较明确,可以直接使用 /来搜索到目标hunk,省去逐个片段判断的麻烦。例如执行 /fun2 来搜索包含 fun2 的代码片段。

git add -p 挑选完之后,建议使用 git diff --cached 确认下,或者在提交之后 git show 确认下改动,如有错漏,及时修正,多退少补。

大部分情况使用s y n就足够了。但如果有些改动是混合在一起的,无法使用s来分割,那就得用 e 来手工编辑了,下回分解吧。

blog: https://www.cnblogs.com/zqb-all/p/13020293.html

公众号:https://sourl.cn/MDcrJA

使用 git add -p 整理 patch的更多相关文章

  1. [Git] Use git add --patch for better commit history and mitigating bugs

    Let's split our changes into separate commits. We'll be able to check over our changes before stagin ...

  2. git add

    一.前言git add命令主要用于把我们要提交的文件的信息添加到索引库中.当我们使用git commit时,git将依据索引库中的内容来进行文件的提交. 二.基本git add <path> ...

  3. Git add 常见用法

        Git add   git add [参数]  [--] <路径> //作用就是将我们需要提交的代码从工作区添加到暂存区,就是告诉git系统,我们要提交哪些文件,之后就可以使用gi ...

  4. Git 常用命令整理

    初始化配置 #配置使用git仓库的人员姓名 git config --global user.name "Your Name Comes Here" #配置使用git仓库的人员em ...

  5. git add 命令详解

    或"表示git会例出索引库中的文件列表中的第个文件."-"表示git会例出索引库中的文件列表中的第个文件到第个文件.回车将执行.如果我们不输入任何东西,直接回车,将结束r ...

  6. git add --all 为啥不能添加空文件夹,这样设计的初衷是

    git add --all 为啥不能添加空文件夹,这样设计的初衷是? 好多项目还得弄个假文件在空文件夹里面占位 这个算设计失误吧,见 https://git.wiki.kernel.org/index ...

  7. (小组)Git 常用命令整理

    Git 常用命令整理 取得Git仓库 初始化一个版本仓库 git init Clone远程版本库 git clone git@xbc.me:wordpress.git 添加远程版本库origin,语法 ...

  8. git add 文档

    GIT-ADD(1) Git Manual GIT-ADD(1) NAME git-add - Add file contents to the index SYNOPSIS git add [-n] ...

  9. Git常见命令整理

    Git常见命令整理 + 注释 git init # 初始化本地git仓库(创建新仓库) git config --global user.name "xxx" # 配置用户名 gi ...

随机推荐

  1. 威联通(NAS)应用篇:自建OwnCloud网盘(百度网盘,拜拜~~~)

    基础环境: 威联通一台 已安装好 ContainerStation 公网 IP(非必须) 自有公网域名 下载镜像文件 提醒:建议先把威联通的自带镜像源改为国内的阿里云镜像源,教程:https://ww ...

  2. Tarjan缩点割点(模板)

    描述:https://www.luogu.com.cn/problem/P3387 给定一个 nn 个点 mm 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权 ...

  3. 猫狗大战("简单的二维背包")

    题面:https://www.luogu.com.cn/problem/P1489 看上去是一道简单的二维费用背包,但是要特别小心循环顺序. Ⅰ先循环物品,再循环限制条件. Ⅱ每一个限制条件都必须从后 ...

  4. Vue实现靠边悬浮球(PC端)

    我想把退出登录的按钮做成一个悬浮球的样子,带动画的那种. 实现是这个样子: 手边没有球形图.随便找一个,功能这里演示的为单机悬浮球注销登录 嗯,具体代码: <div :class="[ ...

  5. 基于环信SDK的IM即时通讯填坑之路(vue)

    公司最近使用第三方环信SDK的进行通信聊天,基本已完成.记录下填坑之路 1.可以通过以下方式引用 WebSDK 1.安装 npm install easemob-websdk --save 2. 先 ...

  6. LabVIEW(数据库自动编号)

    数据库如果字段是自动编号,则在插入数据时,可以不考虑.

  7. IOS App打包发布完整流程

    注册成为开发者 登录苹果开发者中心,点击Accounts,在这里需要你填写你的Appple ID进行登录,如果没有,点击这里申请一个,填写信息就成,这里就不再赘述.申请完成之后,使用申请的AppID进 ...

  8. PHP根据抖音的分享链接来抓包抖音视频

    现在抖音是个很火的短视频平台,上面有许多不错的小视频.今天教大家怎么用PHP技术来获取到抖音上的的内容. 1:打开抖音选中你认为好的视频点击分享,复制链接,然后你会获取到如下的内容: #科比 愿你去的 ...

  9. ubuntu下图形程序自启动的几种方法

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ @ 目录 0.前言 1.带桌面环境的自动启动 1.1 ...

  10. C# 微信公众平台开发(5)--添加图文素材

      微信公众平台开发 --添加素材 关于微信公众号素材管理,我们可以通过接口文档,了解基本详情:http://mp.weixin.qq.com/wiki/10/10ea5a44870f53d79449 ...