Git中两种撤销文件暂存方式的探究

Git中两种撤销文件暂存方式的探究

技术背景

在使用Git进行版本控制时,我们经常会遇到需要撤销文件暂存的情况。Git提供了多种方式来实现这一操作,其中git rm --cached <filePath>git reset -- <filePath>是比较常用的两种。了解它们的区别和适用场景,有助于我们更高效地使用Git。

实现步骤

git rm --cached <filePath>

该命令的作用是将文件从Git的索引中移除,但保留文件在工作树中,使其成为未跟踪的文件。如果文件已经在仓库中提交过,使用该命令后,后续的提交会将文件从仓库中移除。
示例:

1
git rm --cached example.txt

git reset -- <filePath>

此命令用于撤销指定文件的暂存更改,将文件的索引版本替换为仓库中的版本(HEAD)。对于已提交到仓库的文件,它会撤销对文件的修改暂存;对于未版本化的文件,则会完全撤销文件的暂存。
示例:

1
git reset -- example.txt

Git 2.23及以上版本的新命令

在Git 2.23及以上版本中,可以使用git restore --staged <file_name>来撤销文件的暂存。
单个文件操作示例:

1
git restore --staged abc.html

全部文件操作示例:

1
git restore --staged .

核心代码

以下是一些使用这些命令的示例代码:

1
2
3
4
5
6
7
8
9
10
11
# 暂存文件
git add example.txt

# 使用git rm --cached撤销暂存
git rm --cached example.txt

# 使用git reset撤销暂存
git reset -- example.txt

# Git 2.23及以上版本使用git restore --staged撤销暂存
git restore --staged example.txt

最佳实践

  • 当你想完全停止对某个文件的跟踪,并且希望后续提交将其从仓库中移除时,使用git rm --cached <file>
  • 当你只是想撤销对文件的修改暂存,而保留文件在版本控制下时,使用git reset HEAD <file>
  • 在Git 2.23及以上版本中,优先使用git restore --staged <file_name>,因为它的语义更加清晰。

常见问题

问题1:git rm --cachedgit reset HEAD在效果上有什么区别?

如果文件已经在仓库中,git reset HEAD <file>只会撤销当前提交中文件的暂存;而git rm --cached <file>会使文件在未来的提交中都不再被跟踪,直到再次使用git add <file>添加。

问题2:使用git rm --cached后,其他人拉取我的分支会有什么影响?

运行git rm --cached <file>并将分支推送到远程后,其他从远程拉取该分支的人会发现文件实际上已从他们的文件夹中删除,尽管在你本地工作集中文件只是变为未跟踪状态。

问题3:还有其他撤销文件暂存的方法吗?

可以使用git stashgit stash pop组合命令,它会先将更改保存到stash中,然后再恢复更改,允许你重新选择要提交的文件。另外,也可以使用git reflog结合git reset来撤销到某个操作之前的状态。