↓ 跳过正文
  1. 文章/

Git 重写最近一次提交:只保留想提交的文件

目录

提交完成后才发现:这次提交里混进了一个不该提交的文件,或者漏掉了某个文件,又或者提交信息写错了。只要这个提交还没有推送到远端,或者推送后可以安全地强制更新,就可以用几条命令把它“重做”一遍。

本文用一个真实场景,讲清楚下面这三条命令各自做了什么:

git reset --soft HEAD~1
git restore --staged cmd/ofd-wasm/web/index.html
git commit -m "fix(wasm): 移动端缩略图间距从 0 改为 8px" -- cmd/ofd-wasm/web/viewer.js

场景:一次提交里混进了多余的文件
#

假设最近一次提交是这样的:

commit a1b2c3d
    fix(wasm): 移动端缩略图间距从 0 改为 8px

 cmd/ofd-wasm/web/index.html | 12 ++++++------
 cmd/ofd-wasm/web/viewer.js  |  4 ++--
 2 files changed, 10 insertions(+), 6 deletions(-)

其中 viewer.js 才是本次修复的内容,index.html 只是本地调试时顺手改的,不应该出现在这个提交里。

目标很明确:

  • 保留 index.html 的修改,但把它从这次提交中拿出来;
  • 让最近一次提交只包含 viewer.js;
  • 不产生新的“撤销提交”,保持提交历史干净。

三条命令
#

# 1. 软回退最近一次提交,改动全部保留在暂存区
git reset --soft HEAD~1

# 2. 把 index.html 从暂存区移出,修改仍留在工作区
git restore --staged cmd/ofd-wasm/web/index.html

# 3. 只提交 viewer.js
git commit -m "fix(wasm): 移动端缩略图间距从 0 改为 8px" -- cmd/ofd-wasm/web/viewer.js

执行完后再看历史,最近一次提交就只剩下 viewer.js,而 index.html 仍然是工作区里未提交的修改。

每一步到底做了什么
#

理解这三条命令,关键是把 Git 的几个区域分清楚:

工作区(Working Tree)  --git add-->  暂存区(Index)  --git commit-->  提交(HEAD)

git reset 改变的是分支指针和暂存区,git restore 改变的是暂存区或工作区,而 git commit 把暂存区(或指定路径)写成新的提交。

1. git reset --soft HEAD~1:撤销提交,保留改动
#

HEAD~1 表示当前提交的上一个提交。--soft 的意思是:只把当前分支的指针退回到上一个提交,暂存区和工作区都不动。

回退前:

HEAD -> a1b2c3d  (包含 index.html 和 viewer.js)

回退后:

HEAD -> 上一个提交
暂存区:仍然保留 a1b2c3d 带来的全部改动
工作区:完全没有变化

所以执行完这一步,index.html 和 viewer.js 的修改都还在,只是从“已经提交”变成了“已暂存、待提交”。

HEAD~1 和 HEAD^ 在只有一个父提交时效果相同。如果要回退多个提交,可以写 HEAD~2、HEAD~3。

2. git restore --staged <file>:把文件移出暂存区
#

git restore --staged 只修改暂存区,把指定文件的暂存内容恢复成 HEAD 中的版本,不会动工作区里的文件。

执行:

git restore --staged cmd/ofd-wasm/web/index.html

之后:

  • index.html 从“已暂存”变成“已修改、未暂存”,文件内容一点没丢;
  • viewer.js 仍然留在暂存区。

如果想把所有文件都移出暂存区,可以用:

git restore --staged .

3. git commit -- <path>:只提交指定路径
#

普通的 git commit 会提交整个暂存区。加上 -- <path> 后,Git 只提交指定路径的内容,其他已暂存的改动不会进入这次提交。

git commit -m "fix(wasm): 移动端缩略图间距从 0 改为 8px" -- cmd/ofd-wasm/web/viewer.js

这里的 -- 用来分隔“提交参数”和“路径”,避免文件名与分支名、选项名产生歧义。

这条命令会基于当前 HEAD 创建一个新提交,只把 viewer.js 的当前内容写进去,并沿用原来的提交信息。

验证结果
#

提交完成后,用下面几条命令确认:

# 查看最近两条提交
git log --oneline -2

# 查看最近一次提交涉及哪些文件
git show --stat HEAD

# 查看当前工作区状态
git status

预期结果:

  • git show --stat HEAD 中只出现 cmd/ofd-wasm/web/viewer.js;
  • git status 中 index.html 显示为未暂存的修改;
  • 提交历史中没有多出“revert”或“撤销上一次提交”之类的提交。

关于第三条命令的一个细节
#

其实 git commit -- <path> 本身就会忽略其他已暂存的改动,所以第 2 步不是绝对必需的。即使 index.html 还在暂存区,直接执行:

git commit -m "..." -- cmd/ofd-wasm/web/viewer.js

也只会提交 viewer.js。

那为什么还要先执行 git restore --staged?因为这样暂存区的状态更干净、意图更明确,后续执行 git status 或普通 git commit 时不容易误提交。对于初学者来说,显式地把不需要的文件移出暂存区,是更稳妥的做法。

常见变体
#

只是提交信息写错了
#

不需要回退提交,直接修改提交信息:

git commit --amend -m "新的提交信息"

漏了一个文件
#

先补进暂存区,再合并到最近一次提交:

git add 漏掉的文件
git commit --amend --no-edit

--no-edit 表示沿用原来的提交信息。

想沿用原提交信息重做提交
#

回退并调整好暂存区后,可以用 -C 直接复用原提交的信息,避免重新输入:

git reset --soft HEAD~1
git restore --staged 不需要的文件
git commit -C ORIG_HEAD -- 需要提交的文件

ORIG_HEAD 是 reset 之前的位置,-C 表示复制提交信息但不打开编辑器。

想连作者、时间一起改
#

git commit --amend --author="名字 <邮箱>" --no-edit
git commit --amend --date="2026-11-04T10:00:00" --no-edit

reset 的三种模式
#

git reset 常用的三个参数区别如下:

模式 分支指针(HEAD) 暂存区 工作区 典型用途
--soft 移动 不变 不变 重做提交,改动全部保留在暂存区
--mixed(默认) 移动 重置 不变 取消提交和暂存,改动留在工作区
--hard 移动 重置 重置 彻底丢弃提交和改动,慎用

本文使用的是 --soft,因为它不会碰工作区,最安全。

风险和注意事项
#

只重写还没有共享出去的提交
#

重写提交会改变提交的哈希值。如果这个提交已经推送到远端,再次推送时需要强制更新:

git push --force-with-lease

优先使用 --force-with-lease 而不是 --force,它会在远端出现别人新提交时拒绝覆盖,降低误伤风险。

如果分支是多人共用的,重写历史前一定要先和协作者沟通,或者改用普通的“新提交”来修正,例如:

git revert <commit>

确认回退的是正确的提交
#

HEAD~1 只适用于最近一次提交,并且会沿着第一父提交回退。合并提交、变基后的历史可能比想象中复杂,操作前先看一眼:

git log --oneline --graph -5

不要随手使用 --hard
#

git reset --hard HEAD~1 会连同工作区的修改一起丢掉。本文的场景只需要 --soft,没有理由使用 --hard。

万一操作错了,可以用 reflog 找回
#

git reflog 记录了 HEAD 的移动历史。只要提交对象还没被 Git 回收,通常都能找回来:

git reflog
git reset --hard HEAD@{1}

一句话总结
#

git reset --soft HEAD~1 把最近一次提交“拆开”,git restore --staged <file> 把不想要的文件放回工作区,git commit -- <path> 只提交真正需要的文件。这套组合的本质就是重写最近一次提交,适用于提交错文件、漏文件、提交信息写错等常见场景。

相关文章

彩票号码分析助手 - 是否免费使用

·35 分钟
Google Play 市场无过滤功能 Android 版本完全免费! 已有功能列表 # 倍投计算器,目前支持排列三、福彩 3D、快 3、11 选 5、上海时时乐、重庆时时彩等玩法奖项选择。 号码分布工具,支持查看体彩足彩 4 玩法和福彩 3D,体彩 P3、P5、七星彩号码文件分布。 号码拆分工具,可把文件平均拆分多个,如把大文件按 100 行一个小文件。 号码浏览工具,支持号码复制、分享、排序、自由选注(按顺序、随机等方式截取号码)。 合并复式工具,目前支持足彩 14 场(胜负彩)、足彩任选九场、足彩进球彩、足彩半全场、七星彩、排列 5、排列 3 几个彩种号码单式合并。 复式拆分单式工具,支持足彩 14 场(胜负彩)、足彩任选九场、足彩进球彩、足彩半全场、七星彩、排列 5、排列 3、双色球、大乐透、七乐彩、15 选 5 几个彩种号码复式分解单式。 奖金计算工具,支持双色球、大乐透、七乐彩。 彩票网站连接,显示各地福彩、体彩中心网站 最新开奖号或历史奖号,支持按期数、按期号、按日期、按星期查询历史开奖号码,已支持福彩 3D、双色球、七乐彩,体彩排列 3、排列 5、七星彩、大乐透、足彩胜负彩(任选 9 场)、6 场半全场、4 场进球几个彩种。 标准选号工具,支持福彩 3D、排列 3、双色球、大乐透、七乐彩、七星彩、排列 5、足彩 14 场、足彩 9 场、半全场、进球彩、北京单场、竞彩足球玩法的复式选号。 每个彩种已支持查看常用条件的折线图、柱状图、散点图、走势表格、遗漏数据查询。 集合运算工具,支持交集、差集、合并(含重复)、并集(去重复)、不同注、交集筛选(重复次数)。 足彩 14 场、9 场媒体制作工具,可大量制作随机足彩媒体。 福彩3D 走势图表条件列表 # 折线图

如何调整 Windows电脑屏幕的分辨率

·1 分钟
如出现下面情况可考虑调整屏幕分辨率? 软件界面显示不全,屏幕分辨率太小,可调大分辨率 软件界面显示太小,屏幕分辨率太大,可调小分辨率 软件界面显示混乱或某些按钮字体不正常,可修改屏幕字体缩放为默认 在桌面空白的地方右键点击,会看到屏幕分辨率 或显示设置的字样,打开屏幕分辨率设置界面

如何清理 Android APP 缓存或软件初始化

·1 分钟
安卓手机装的应用越多,占用的空间也越大,我们可以删除掉部分应用的缓存或应用数据。 APP 的一些重要数据,例如软件参数设置等重要数据会放在应用数据,其他不重要的会存缓存。 清空数据:相当于卸载后再重新安装应用一样。 清空缓存:不会影响 APP 正常使用,是清除一些不重要的数据,例如软件临时下载或缓存数据,如您的手机空间够大建议不要清除,也许能提高软件部分操作速度。