使用 Git add -p 暂存补丁

Hacker News Top 工具

摘要

关于使用 git add -p 交互式暂存更改块的教程,允许选择性提交并保持更干净的版本控制历史。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/29 21:57

# 使用 git add 暂存补丁 来源:https://www.simonholywell.com/post/git-add-p/ ## 简介 如果你还没用过 `git add -p` 来暂存提交,那您就错过了一个好工具。它能让你交互式地暂存整个文件或其中一部分,让你的 Git 提交过程拥有更强的控制力。 ## 为什么要这样做? 以下是我在工作流程中偏好使用 `git add -p` 的一些原因。最主要的是,它让我在暂存变更时同时审查代码,我经常通过这种方式发现错误。通过暂存时审查变更,我能捕捉到那些在初期编码或内容创作时悄悄溜进来的 bug、拼写错误和其他问题。 但还有一个额外好处:它允许我只暂存文件的一部分。Git(有点奇怪地)把这些部分称为“块”(hunks),所以下文我将沿用这个术语。这个功能在你有一堆变更、但又希望将它们分组到不同提交中时特别有用。想象一下,你在一个文件的不同部分做了几个相关的改动,借助 `git add -p`,你可以有选择地将这些改动暂存到一起,确保提交更干净、更有条理。 ## 暂存文件的一部分 下面是一个界面示例,展示了差异并提示你“暂存此块?”。 ``` diff --git a/main.mts b/main.mts index e1132f2..8f7c279 100644 --- a/main.mts +++ b/main.mts @@ -1,2 +1,4 @@ export const add = (a, b) => a + b +export const div = (a, b) => a / b export const sum = (xs) => xs.reduce((acc, x) => sum(acc, x)) +export const avg = (xs) => div(sum(xs), xs.length) (1/1) 暂存此块 [y,n,q,a,d,s,e,?]? ``` 在最简单的形式下,我们可以输入 `y` 来暂存那段差异以便提交,或者输入 `n` 则不暂存。在这个例子中,我还没准备好提交 `avg` 函数,但想把 `div` 推送上去,所以我输入 `s` 将块拆分成更小的块。Git 接着问: ``` 拆分为 2 个块。 @@ -1,2 +1,3 @@ export const add = (a, b) => a + b +export const div = (a, b) => a / b export const sum = (xs) => xs.reduce((acc, x) => sum(acc, x)) (1/2) 暂存此块 [y,n,q,a,d,j,J,g,/,e,?]? ``` 所以我输入 `y` 来暂存这个块以便提交,Git 接着显示下一个块: ``` @@ -2 +3,2 @@ export const sum = (xs) => xs.reduce((acc, x) => sum(acc, x)) +export const avg = (xs) => div(sum(xs), xs.length) (2/2) 暂存此块 [y,n,q,a,d,K,g,/,e,?]? ``` 记着我只想提交 `div` 函数,所以我输入 `q` 退出交互式块暂存。交互结束后,我回到命令行提示符,然后可以接着执行 `git commit` 或其他必要命令。 ## 检查是否生效 如果我运行 `git status` 查看暂存的文件,会发现该文件(`main.mts`)出现在两部分中:待提交和未暂存以待提交。这正是我们想要的,因为我们只暂存了文件的一部分! ``` 位于分支 main 您的分支领先 'origin/main' 1 个提交。 (使用 "git push" 发布本地提交) 要提交的变更: (使用 "git restore --staged <文件>..." 以取消暂存) 修改: main.mts 未暂存以备提交的变更: (使用 "git add/rm <文件>..." 以更新要提交的内容) (使用 "git restore <文件>..." 以丢弃工作区中的改动) 修改: main.mts ``` 通过有选择地只暂存文件的一部分,我们成功地为即将进行的提交准备了一个单独的块——一个补丁。 ## 其他选项 上面看到的选项列表(`[y,n,q,a,d,s,e,?]`)是缩略版,你可以输入 `?` 获取扩展的帮助文档。以下是一些在交互式块暂存中可用的响应选项,取自 [Git 文档](https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging#_staging_patches)。你会发现上面看到的列表里还有很多选项未列出。 - `y`:暂存此块 - `n`:不暂存此块 - `a`:暂存此块及文件中所有剩余的块 - `d`:不暂存此块及文件中所有剩余的块 - `g`:选择一个块跳转到 - `/`:搜索与给定正则表达式匹配的块 - `j`:暂不决定此块,查看下一个未决定的块 - `J`:暂不决定此块,查看下一个块(无论是否已决定) - `k`:暂不决定此块,查看上一个未决定的块 - `K`:暂不决定此块,查看上一个块(无论是否已决定) - `s`:将当前块拆分为更小的块 - `e`:手动编辑当前块 - `?`:打印帮助 ## 何时不使用 我几乎每个工作日提交时都会使用 `git add -p`,但有两种情况不用: 1. 需要首次提交一个新创建的文件——新文件没有之前的版本可以用来对比,因此 `git add -p` 无法展示差异供你批准暂存。 2. 极少数情况下,当我想提交整个目录并且对其内容非常确信时,我会选择标准方式。不过即使在这种边缘情况,我也常常发现自己会用 `git add -p` 以获得更精细的控制。 ## 总结 将 `git add -p` 融入你的工作流程,你会简化 Git 和提交过程。毫不夸张地说,我几乎在每次需要向 Git 提交变更集时都会使用这个技巧。它让我在暂存代码时轻松审查代码,并精确控制每个提交中包含什么内容。

相似文章

Git history 命令值得更多关注

Hacker News Top

文章重点介绍了新的 `git history` 命令及其 `fixup`、`reword` 和 `split` 子命令,这些命令提供了原子化且感知分支的提交历史编辑功能,带来了类似 jj 的益处,而无需切换版本控制系统。

git-absorb:自动的git commit --fixup

Lobsters Hottest

git-absorb自动为暂存的更改创建fixup提交,实现了与hg absorb类似的功能。它与git的autosquash集成,简化了应用代码审查反馈的过程,无需手动查找提交的SHA。

接受混乱的 git 历史

Lobsters Hottest

一篇博客文章,讨论两种 git 工作流理念——频繁提交与谨慎变基——并解释为何在大型团队中,鉴于团队的韧性,混乱的历史是可以接受的,文中还提到了 GitHub 的新堆叠 PR 功能。

Show HN: Codiff,本地差异审查工具

Hacker News Top

Codiff 是一款轻量级本地 diff 查看器,用于审查 Git 暂存和未暂存的更改,支持基于 LLM 的逐步讲解和内联审查评论。