其他

不要慌!了解Git的逆向操作,轻松撤回提交

转载:不要慌!了解Git的逆向操作,轻松撤回提交

 在使用 Git 进行版本控制时,逆向操作同样至关重要。本文将探讨如何有效地撤回已完成的操作,包括从暂存区回到工作区、从本地仓库回到暂存区和工作区,以及清空工作区的情况。这些逆向操作不仅可以有效纠正错误,还能帮助开发者灵活应对代码变更。接下来的内容将详细介绍不同逆向操作的使用场景、命令及其影响,确保用户能够熟练掌握 Git 的强大功能。

什么是逆向操作?


Git 操作流程图:

对于正向操作来说,Git 操作是由 workspace进行add操作进入Index,再commitRepository,最后pushRemote

但有时候也需要一些逆向操作,比如数据文件已经由 workspace进行add操作进入Index了,但是发现本次提交的数据有些问题,想把它撤回来,即撤到workspace中;或者数据文件已经commitRepository了,但是,我们想把数据回退,将其回退到Index或 workspace,甚至删除提交记录等。这就需要逆向操作

逆向操作思维导图:

暂存区 到 工作空间 


如果数据已经由工作空间(workspace)提交(add)到暂存区(Index)了,现在想要回退,应该怎么操作?

可以使用git restore -S 命令,它主要用于将某个文件的状态恢复为指定的状态。

git restore -S 的用途:

  • 恢复文件状态:可以将文件恢复到某个特定的提交(commit)状态。
  • 签名验证: 使用 -S 选项可以确保恢复的内容经过签名验证,符合安全标准。

使用示例:假设有一个文件 example.cc,可以使用以下命令将其恢复到指定的提交状态。

git restore -S example.cc

这样,原本在暂存区的example.cc数据将回退到Untracked files状态。

本地仓库 到 暂存区、工作区及清空 


如果数据已经由暂存区(Index)提交(commit)到本地仓库(Repository)了,现在想要回退,应该怎么操作?

可以使用git reset --soft, git reset --mixed 和 git reset --hard ,它们的区别在于它们对工作区、暂存区和提交历史的影响程度不同。

  1. git reset --soft:主要是回退到 暂存区。
    • 影响范围:仅影响 HEAD 的位置。
    • 效果:不更改工作区和暂存区的内容,仅仅移动 HEAD 指针。
    • 适用场景:适合于需要修改最近提交历史的情况,但不想丢失当前工作区和暂存区的变更。
  2. git reset --mixed:主要是回退到 工作区(workspace),--mixedgit reset命令的默认参数。
    • 影响范围:影响 HEAD 的位置和暂存区。
    • 效果:不更改工作区内容,但是会将 HEAD 移动到指定提交,同时将这个提交之后的修改放入暂存区。
    • 适用场景:当需要撤销提交并且希望保留更改但不立即提交时使用。可以重新选择要包含在下一次提交中的更改。
  3. git reset --hard:完全取消提交和相关更改,就像重来没提交过一样。
    • 影响范围:影响 HEAD、暂存区和工作区。
    • 效果:将 HEAD 指向指定的提交,同时重置暂存区和工作区到该提交,丢弃所有未提交的更改。
    • 适用场景:适合于需要完全撤销到某个提交的情况,且不关心之前的修改。

git reset --soft命令用于重置当前分支的 HEAD 到一个指定的提交(commit),但不会更改工作区的文件或暂存区的内容。这个命令主要用于在不丢失当前工作内容的情况下,调整提交历史。因此--soft的方式是一种比较温和的方式进行重置。

语法:

git reset <--soft or --mixed or --hard> <commit or HEAD>

选择 git reset --soft 的场景:

  • 修改最近的提交历史:当你需要修改最近的一个或多个提交时,可以使用 git reset --soft 将 HEAD 重置到相应的提交,然后重新组织和提交更改。
  • 保留当前工作内容:如果你希望保留当前工作区和暂存区的内容,并在之后再次提交它们,git reset --soft 是一个不会丢失更改的选择。
  • 合并多次提交:可以用 git reset --soft 将多个小的提交合并成一个更大的提交,这样可以保持提交历史的整洁性和可读性。

工作区清空 


要将工作区的数据清空,可以使用git checkout命令。主要用于在不同的分支之间切换、恢复文件或提交状态,以及创建新分支。

git checkout命令可以丢弃未暂存的更改,但是不会删除新文件。例如:

# 丢弃所有未暂存的更改:
git checkout .
# 丢弃自上次提交以来对文件的所有未暂存更改
git checkout <file>

git checkout -f 是 Git 中用于强制切换分支或者恢复文件到某个状态的命令。

基本用法:

  • 切换分支:当你想要切换到另一个分支,而当前分支上有未提交的更改时,执行 git checkout -f <branch> 会强制你切换到指定的 <branch>,并丢弃当前分支上的所有未保存的更改。也就是说,未提交的更改会被清除。
  • 恢复文件:如果你想要恢复某些文件到最后一次提交的状态,可以使用 git checkout -f <file>。这也会丢弃该文件在工作区中的更改,恢复为上次提交的状态。但是不会删除新文件。

例子:

# 强制切换到分支 `feature-branch`
git checkout -f feature-branch

# 强制恢复文件 `example.txt` 到最后一次提交的状态
git checkout -f example.txt