使用 git add -p 整理 patch
背景
当我们修改了代码准备提交时,本地的改动可能包含了不能提交的调试语句,还可能需要拆分成多个细粒度的 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 就会自动展示下一个片段,继续询问我们。
这样对片段使用 y 和 n,我们就可以只挑选出涉及 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的更多相关文章
- [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 ...
- git add
一.前言git add命令主要用于把我们要提交的文件的信息添加到索引库中.当我们使用git commit时,git将依据索引库中的内容来进行文件的提交. 二.基本git add <path> ...
- Git add 常见用法
Git add git add [参数] [--] <路径> //作用就是将我们需要提交的代码从工作区添加到暂存区,就是告诉git系统,我们要提交哪些文件,之后就可以使用gi ...
- Git 常用命令整理
初始化配置 #配置使用git仓库的人员姓名 git config --global user.name "Your Name Comes Here" #配置使用git仓库的人员em ...
- git add 命令详解
或"表示git会例出索引库中的文件列表中的第个文件."-"表示git会例出索引库中的文件列表中的第个文件到第个文件.回车将执行.如果我们不输入任何东西,直接回车,将结束r ...
- git add --all 为啥不能添加空文件夹,这样设计的初衷是
git add --all 为啥不能添加空文件夹,这样设计的初衷是? 好多项目还得弄个假文件在空文件夹里面占位 这个算设计失误吧,见 https://git.wiki.kernel.org/index ...
- (小组)Git 常用命令整理
Git 常用命令整理 取得Git仓库 初始化一个版本仓库 git init Clone远程版本库 git clone git@xbc.me:wordpress.git 添加远程版本库origin,语法 ...
- git add 文档
GIT-ADD(1) Git Manual GIT-ADD(1) NAME git-add - Add file contents to the index SYNOPSIS git add [-n] ...
- Git常见命令整理
Git常见命令整理 + 注释 git init # 初始化本地git仓库(创建新仓库) git config --global user.name "xxx" # 配置用户名 gi ...
随机推荐
- Java——Java集合那些事
集合概述: 集合和数组都可以保存多个对象,但是数组的长度不可变,集合可以保存数量变化的数据.java中的集合类主要由两个接口派生出,Collection和Map Collection接口和Iterat ...
- sqlserver2005定期备份和清除
1.打开管理->维护计划 2.右键点击新建维护计划 3.给新的维护计划自定义命名 4.可以看左下角的维护方式 5.拖动“备份数据库”到右边 6.选中,编辑备份方式 7.选择备份方式,所有数据库, ...
- SecureCRT怎么将本级文件上传到CentOS
进入到想要放文件的路径,不然会默认放在当前路径下: 输入 rz -------------------------------------------------------------------- ...
- shell命令之巧用cut
需求:取出日志中ip字段,并进行统计排序 .一般用用awk命令 假如ip地址为第一个字段 那么 awk ‘{print $1}’ 文件名 |sort |uniq -c|sort-nr 那如果不是第一个 ...
- LeetCode--Sort Array By Parity && N-Repeated Element in Size 2N Array (Easy)
905. Sort Array By Parity (Easy)# Given an array A of non-negative integers, return an array consist ...
- 【Hadoop离线基础总结】MapReduce增强(上)
MapReduce增强 MapReduce的分区与reduceTask的数量 概述 MapReduce当中的分区:物以类聚,人以群分.相同key的数据,去往同一个reduce. ReduceTask的 ...
- 《Vue.js 2.x实践指南》 已出版
<Vue.js 2.x实践指南>其实在一年前就已经完稿了,只是由于疫情的缘故耽搁了很久才下厂印刷.阅读本书需要具备HTML.CSS和JS基础,本书针对的用户群体主要是:想要快速学习vue技 ...
- Linux内核驱动学习(八)GPIO驱动模拟输出PWM
文章目录 前言 原理图 IO模拟输出PWM 设备树 驱动端 调试信息 实验结果 附录 前言 上一篇的学习中介绍了如何在用户空间直接操作GPIO,并写了一个脚本可以产生PWM.本篇的学习会将写一个驱动操 ...
- Git使用教程之在github上创建项目(三)
继续~ 登录你的github账号,创建一个新项目 1. 2. 至此,github的项目也创建完成了.
- jvm启动参数调优
1.背景 eclipse启动了一个项目,用了15分钟,我佛了,在家办公也懒得弄一直没管,好嘛,越用越气,越来越慢,现在启动一次要半小时了,气不气,然后下定决心调优一下. 2.知识库(自认为调优重要的几 ...