当前位置:

首页 > 编程开发 > git提交时怎么只选部分修改?手把手教你精准暂存

git提交时怎么只选部分修改?手把手教你精准暂存

从普通目录完成第一次本地提交其实并不难,难的是真实开发很少会一直保持"只改一个文件,然后立刻提交"这种理想状态。 写一个功能的时候,往往会出现好几种情况混在一起: 当前真正要提交的代码; 顺手改了一下但应该单独提交的文档; 运行程序产生的日志文件; 只属于本机环境、不上传配置。 这时候,add 和

从普通目录完成第一次本地提交其实并不难,难的是真实开发很少会一直保持"只改一个文件,然后立刻提交"这种理想状态。

git提交时怎么只选部分修改?手把手教你精准暂存

写一个功能的时候,往往会出现好几种情况混在一起:

  • 当前真正要提交的代码;
  • 顺手改了一下但应该单独提交的文档;
  • 运行程序产生的日志文件;
  • 只属于本机环境、不上传配置。

这时候,addcommit 本身并不难,真正需要判断的是:

哪些变化属于这次提交,哪些应该留在外面?

四个检查窗口

一次提交前后,可以从四个角度观察仓库:

想知道什么命令
哪些路径发生了变化,分别位于哪一层git status --short
工作区相对暂存区还有哪些具体变化git diff
暂存区相对当前提交准备记录什么git diff --cached,也可以使用 git diff --staged
提交完成后形成了什么历史git log --oneline、git show

status 先告诉我们"哪里有变化",diff 再说明"内容怎么变的",logshow 用于提交后核对已经形成的记录。简单来说,就是一套从"发现问题"到"确认结果"的完整流程。

准备独立实验仓库

下面的初始化和第一次提交只用于建立一个可复现的前置状态。如果本地已有同名目录,建议换一个新名字。

mkdir commit-check-lab
cd commit-check-lab
git init
git config user.name "Git Blog Lab"
git config user.email "git-blog@example.invalid"

printf "login validationn" > app.txt
printf "old documentationn" > README.md
git add app.txt README.md
git commit -m "chore: initialize commit check lab"

现在仓库里有一个初始提交,工作区是干净的。

先处理不应进入仓库的文件

运行程序时经常会产生日志,本地开发也可能需要只属于个人环境的配置。先制造两个未跟踪文件:

printf "debug outputn" > debug.log
printf "local development configurationn" > .env
git status --short

输出会包含:

?? .env
?? debug.log

它们都是工作区中的未跟踪文件。如果直接执行 git add .,就可能把不该进仓库的东西也一起放进暂存区。

解决方法是在仓库根目录创建 .gitignore

printf "*.logn.envn" > .gitignore
git status --short

现在输出中不再显示 debug.log.env,只会出现新的 .gitignore

?? .gitignore

忽略规则本身是项目约定,应该进入版本历史:

git add .gitignore
git commit -m "chore: ignore logs and local environment files"

.gitignore 的两个边界

第一,.gitignore 主要影响尚未被跟踪的路径。文件如果已经进入提交,后来补写忽略规则并不会自动停止跟踪。

如果误跟踪的是普通日志或本地生成文件,可以在写好忽略规则后停止跟踪:

git rm --cached <文件>
git add .gitignore
git commit -m "chore: stop tracking generated file"

--cached 会把删除记录放入暂存区,但保留本地工作区文件。目录需要配合 -r 使用。执行后应先用 git status 确认暂存内容,再提交这次规则变更。

第二,忽略规则不是凭据泄露后的补救工具。密钥、Token 或密码一旦进入历史,应立即轮换或作废,再根据团队流程处理仓库历史。仅仅删除文件或补写 .gitignore,不能让已经泄露的值失效。

制造一个混合修改现场

printf "check empty usernamen" >> app.txt
printf "new usage examplen" >> README.md
printf "another debug linen" >> debug.log
git status --short

输出:

 M README.md
 M app.txt

debug.log 仍存在于本地,但因为匹配 .gitignore,不会出现在普通状态结果中。

git status --short 在文件名前使用两个位置显示状态,可以写成:

XY 文件名
  • 第一个位置 X:已经进入暂存区的变化;
  • 第二个位置 Y:仍在工作区、尚未暂存的变化。

当前两个文件显示为 M:第一个位置为空,第二个位置是 M,说明文件只在工作区发生了修改,还没有进入暂存区。

diff:检查具体改了什么

先检查准备作为当前功能提交的文件:

git diff -- app.txt

这里会看到新增的 check empty username

再检查文档:

git diff -- README.md

这里会看到另一个独立意图:补充使用示例。

普通 git diff 比较的是工作区和暂存区,不会展示普通未跟踪文件的内容。因此,检查现场时不能只看 diff,还要先看 status;否则可能漏掉尚未跟踪、也未被忽略的文件。

只选择属于本次提交的变化

这次先提交登录校验,不把文档修改混进去:

git add app.txt
git status --short

输出:

 M README.md
M  app.txt

app.txtM 进入左列,说明它已经被暂存;README.md 的修改仍在工作区。

提交前检查暂存区中的实际内容:

git diff --cached -- app.txt

这里只应该出现与登录校验有关的变化。确认边界正确后再提交:

git commit -m "feat: validate empty username"

一次提交可以同时包含代码、测试和必要文档,关键不是"只能改一个文件",而是这些变化能否共同表达同一个意图,并且可以一起评审和撤销。

提交后不要立即离开

提交完成后先看状态:

git status --short

输出:

 M README.md

这说明功能变化已经提交,文档修改仍然安全地留在工作区。提交不会自动带走没有进入暂存区的变化。

接着查看最近历史:

git log --oneline -3

这条命令用于快速确认最近提交的顺序和说明。

查看刚才那次提交涉及哪些文件:

git show --stat HEAD

查看提交的完整内容:

git show HEAD

HEAD 表示当前检出位置对应的提交。在通常的分支状态下,它通过当前分支定位到最新提交。

确认功能提交没有混入 README 后,再把文档作为独立提交:

git add README.md
git diff --cached -- README.md
git commit -m "docs: add usage example"
git status

最后的状态应该是干净的。

同一个文件包含两个意图怎么办

按路径执行 git add app.txt 会选择这个文件当前的全部变化。但同一个文件也可能同时包含两个不同意图。

此时可以交互式选择差异块:

git add --patch app.txt

Git 会把变化分成若干块,让我们逐块决定是否暂存。没有选中的部分仍留在工作区,不会被删除。

完成后分别检查:

git diff --cached -- app.txt
git diff -- app.txt

第一条查看已经选入下次提交的变化,第二条查看仍留在工作区的变化。如果一个差异块内部仍然混着两个意图,可以继续拆分差异块,或者先回到编辑器整理内容。

为什么不把 commit -am 当作默认动作

git commit -am "message"

这个写法会在提交前自动暂存所有已跟踪文件的修改和删除,并提交它们执行命令时的当前内容,但不会纳入普通未跟踪文件。

但问题在于,它也会绕过"选择路径 → 检查暂存差异"这个过程。如果同一个已跟踪文件在暂存后又继续修改,-a 会把后续工作区修改一起纳入提交,可能破坏原本选择好的边界。

只有当所有已跟踪变化都属于同一意图,并且已经确认过现场时,这个快捷方式才比较合适。

一次提交前后的稳定检查顺序

git status --short
  ↓
git diff
  ↓
排除不应跟踪的路径,选择本次相关变化
  ↓
git diff --cached
  ↓
git commit
  ↓
git status --short
  ↓
git log --oneline / git show

提交之前检查选择,提交之后核对结果。暂存区不是必须机械经过的一个步骤,而是编辑下一次历史记录的地方。

总结

一次清晰的提交不是靠一句漂亮的提交说明产生的,而是从检查现场、排除无关文件、选择同一意图的变化开始。status 定位路径,diff 核对内容,暂存区确定边界,logshow 则帮助确认最终写入了怎样的历史。

参考资料:

  • Git 官方资料:Recording Changes to the Repository
  • Git 官方资料:Viewing the Commit History
  • Git 官方文档:git-status
  • Git 官方文档:git-diff
  • Git 官方文档:git-add
  • Git 官方文档:git-commit
  • Git 官方文档:git-log
  • Git 官方文档:git-show
  • Git 官方文档:gitignore
本文内容来源于互联网,如有侵权请联系删除。
作者最新文章
编程开发
相关文章 更多
C++动态数组初始化怎么写?常用语句与代码示例
C++动态数组初始化怎么写?常用语句与代码示例

深入解析C++中动态数组的初始化机制,涵盖new操作符的不同用法、基本类型与类对象的初始化差异,以及为何在现代C++开发中应优先使用std::vector。

using namespace 使用中遇到的问题怎么解决
using namespace 使用中遇到的问题怎么解决

命名空间的基本概念与常见引入问题在C++等编程语言中,命名空间(namespace)是一种将代码标识符(如变量、函数、类名)封装在特定名称下的机制,其主要目的是避免命名冲突,尤其是在大型项目或使用多个第三方库时。使用“using namespace”指令可以将指定命名空间中的所有名称引入当前作用域,

c语言函数递归 实操经验总结:这些技巧很实用
c语言函数递归 实操经验总结:这些技巧很实用

理解递归的基本原理在C语言中,递归是一种函数调用自身的编程技术。要掌握它,首先需要理解其核心思想:将一个复杂的大问题,分解为一个或几个与原问题相似但规模更小的子问题,直到子问题足够简单,可以直接求解。这个过程通常包含两个关键部分:递归出口和递归体。递归出口定义了问题何时不再继续分解,即最简单、可直接

c语言函数递归 怎么选?常见方案对比分析
c语言函数递归 怎么选?常见方案对比分析

递归函数的基本概念与适用场景在C语言编程中,递归是一种函数调用自身的编程技巧。它并非适用于所有问题,但在处理某些具有自相似结构的问题时,能提供极其清晰和优雅的解决方案。递归的核心思想是将一个大规模问题分解为一个或多个同类型但规模更小的子问题,直到子问题简单到可以直接求解。典型的适用场景包括树形结构的

Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解
Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解

理解内存管理的基石在Objective-C的编程世界中,内存管理是开发者必须掌握的核心技能之一。它直接关系到应用的性能、稳定性与资源利用效率。与一些采用自动垃圾回收机制的语言不同,Objective-C在很长一段时间里,依赖一套基于引用计数的、需要开发者部分介入的管理规则。这套规则的核心思想是明确的

如何正确使用 dealloc 以避免 iOS 应用中的内存泄漏
如何正确使用 dealloc 以避免 iOS 应用中的内存泄漏

理解 dealloc 的角色与时机在 iOS 应用开发中,内存管理是保障应用性能与稳定性的基石。dealloc 方法是 Objective-C 中对象生命周期结束时的关键回调,它标志着对象即将被系统回收内存。正确理解其触发时机至关重要:当一个对象的引用计数降为零时,运行时系统会自动调用该对象的 de

深入理解 Objective-C 中的 dealloc 方法:内存管理核心机制
深入理解 Objective-C 中的 dealloc 方法:内存管理核心机制

内存管理的基石在Objective-C的世界里,内存管理是开发者必须掌握的核心技能之一。作为一门在手动引用计数(MRC)时代诞生的语言,Objective-C要求程序员对对象的生命周期有清晰的认识。dealloc方法正是这一生命周期中至关重要的终点站。它是一个实例方法,当对象的引用计数降为零时,系统

理解 native2ascii:Java 国际化开发中的字符编码工具
理解 native2ascii:Java 国际化开发中的字符编码工具

native2ascii 工具的基本定位在Ja va应用程序的国际化与本地化开发过程中,处理非拉丁字符集是一个常见且关键的环节。Ja va内部使用Unicode字符集来统一表示全球各种语言的文字,但其属性文件(.properties)在历史上要求使用ASCII编码,或者更准确地说,要求非ASCII字

如何使用 native2ascii 转换中文字符为 Unicode 转义序列
如何使用 native2ascii 转换中文字符为 Unicode 转义序列

理解 native2ascii 工具的基本用途在软件开发,特别是涉及国际化处理的场景中,开发者常常需要处理不同编码的文本资源。native2ascii 是 Ja va 开发工具包(JDK)中提供的一个命令行实用程序,其主要功能是将包含本地字符编码(非ASCII字符)的文件,转换为包含 Unicode

Java native2ascii 命令详解:解决属性文件乱码问题
Java native2ascii 命令详解:解决属性文件乱码问题

native2ascii 命令的由来与作用在Ja va开发中,处理国际化资源文件是一个常见需求。资源文件通常以.properties格式存储,用于支持多语言界面。然而,Ja va属性文件默认采用ISO-8859-1字符集编码,这导致了一个直接的问题:当文件中包含非拉丁字符(如中文、日文、韩文等)时,

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件
macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

Mac软件 更多
灵活计算器
灵活计算器
macOS/iOS/Android

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师
macOS

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

WINDOWS 更多
Windows 10
Windows 10
Windows

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘
Windows/macOS/iOS/Android

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。