如何在提交前撤销 'git add'
如何在提交前撤销 ‘git add’
技术背景
在使用Git进行版本控制时,git add
命令用于将工作目录中的文件添加到暂存区,准备提交到版本库。但有时我们可能会误添加了某些文件,或者添加了不需要提交的文件,而此时还未执行 git commit
命令。这就需要一种方法来撤销 git add
操作,将文件从暂存区移除,避免这些文件被包含在后续的提交中。
实现步骤
撤销单个文件的 git add
- 使用
git reset
命令:从Git 1.8.2版本开始,可使用以下命令撤销单个文件的git add
操作:
1 |
|
例如,若误添加了 myfile.txt
,可使用 git reset myfile.txt
来撤销。在旧版本的Git中,该命令等同于 git reset HEAD <file>
,不过在现代版本中,即使还未进行任何提交也可使用。
- 使用
git rm --cached
命令:当文件是新添加到仓库且未被跟踪时,可使用该命令:
1 |
|
例如,git rm --cached myfile.txt
。但要注意,git rm
若不使用 --cached
选项会删除本地工作副本,而使用 --cached
则仅从索引中移除文件,工作树中的文件会保留。
撤销所有文件的 git add
- 使用
git reset
命令:
1 |
|
该命令会将所有已添加到暂存区的文件移除,但不会改变工作目录中的文件。在旧版本Git中,等同于 git reset HEAD
,现代版本即使未提交也可使用。
- 使用
git rm -r --cached .
命令:当仓库还没有任何提交时,可使用该命令递归地移除当前目录下所有已添加的文件:
1 |
|
使用Git GUI工具撤销
若不想使用命令行,可使用 git gui
工具:
1 |
|
打开窗口后,手动取消勾选“Staged changes (will commit)” 中的文件。
核心代码
撤销单个文件
1 |
|
撤销所有文件
1 |
|
创建别名
为方便使用,可创建别名:
1 |
|
之后可使用 git unadd
或 git unstage
来撤销 git add
操作,例如:
1 |
|
最佳实践
- 使用
git status
命令:在进行操作前,可先使用git status
命令查看暂存区和工作区的状态,该命令会给出撤销git add
的提示。 - 使用
.gitignore
文件:在项目开始时,创建.gitignore
文件,将不需要跟踪的文件或目录添加到该文件中,避免误添加。例如:
1 |
|
- 使用
git add -p
命令:该命令允许交互式地添加文件的部分更改,可避免一次性添加过多不需要的更改。
常见问题
提示 “fatal: Failed to resolve ‘HEAD’ as a valid ref.”
这通常是因为仓库还没有进行任何提交,HEAD 引用不存在。可使用 git rm --cached
命令来撤销 git add
,或者先进行一次提交,之后就可正常使用 git reset
命令。
无法恢复被覆盖的暂存版本
若错误的 git add
操作覆盖了之前已暂存但未提交的版本,通常无法安全地恢复。不过可通过一些复杂的方法尝试恢复,如在 .git/objects
目录中查找创建时间符合的文件,使用 git cat-file -p <object-id>
命令查看内容;或者使用 git fsck --unreachable
或 git fsck --lost-found
命令查找未引用的对象。
git reset
和 git rm --cached
的区别
git reset HEAD <file>
适用于撤销已跟踪文件的更改,将文件从暂存区移除,同时使暂存区的文件内容与 HEAD 指向的版本一致。git rm --cached <file>
适用于撤销新添加到仓库且未被跟踪的文件,会将文件从暂存区移除,并且在后续提交时会标记该文件为删除状态。