欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Git命令(撤销更改)

程序员文章站 2022-03-10 17:22:20
...

更改最后一个 commit

你已经使用 git commit 命令提交了大量的 commit。现在,借助 –amend 选项,你可以更改最近的 commit

$ git commit --amend

git commit --amend 使你能够包含忘记包含的文件(或文件更改)。你可以执行新的 commit 并更新文件,但是这样就会出现两个 commit 执行完全相同的任务。相反,你可以运行 git commit --amend更新最近的 commit,而不是创建新的 commit

具体更新步骤:

  • 编辑文件
  • 保存文件
  • 暂存文件
  • 运行 git commit --amend

还原 commit

git revert 命令用于还原之前创建的 commit:

$ git revert <SHA-of-commit-to-revert>

此命令:

  • 将撤消目标 commit 所做出的更改
  • 创建一个新的 commit 来记录这一更改

假设 commit A 添加了一个字符,如果 git 还原 commit A,那么 git 将创建一个新的 commit,并删掉该字符。如果删掉了一个字符,那么还原该 commit 将把该内容添加回来!

git-revert git 文档

重置 commit

初看,重置(reset) 似乎和 还原(revert) 相似,但它们实际上差别很大。还原会创建一个新的 commit,并还原或撤消之前的 commit。但是重置会清除 commit!

一定要谨慎使用 git 的重置功能。这是少数几个可以从仓库中清除 commit 的命令。如果某个 commit 不再存在于仓库中,它所包含的内容也会消失。

为了减轻你的压力,澄清下,git 会在完全清除任何内容之前,持续跟踪大约 30 天。要调用这些内容,你需要使用 git reflog 命令。请参阅以下链接以了解详情:

相关 commit 引用

有时候可能需要引用相对于另一个 commit 的 commit,我们可以使用特殊的“祖先引用”字符来告诉 git 这些相对引用。这些字符为:

  • ^ – 表示父 commit
  • ~ – 表示第一个父 commit

我们可以通过以下方式引用之前的 commit:

  • 父 commitHEAD^HEAD~HEAD~1
  • 祖父 commitHEAD^^HEAD~2
  • 曾祖父 commitHEAD^^^HEAD~3

^~ 的区别主要体现在通过合并而创建的 commit 中。合并 commit 具有两个父级。对于合并 commit,^ 引用用来表示第一个父 commit,而 ^2 表示第二个父 commit。第一个父 commit 是当你运行 git merge 时所处的分支,而第二个父 commit 是被合并的分支

我们来看一个示例,这样更好理解。这是我的 git log 当前的显示结果:

* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
*   796ddb0 Merge branch 'heading-update'
|\  
| * 4c9749e (heading-update) Set page heading to "Crusade"
* | 0c5975a Set page heading to "Quest"
|/  
*   1a56a81 Merge branch 'sidebar'
|\  
| * f69811c (sidebar) Update sidebar with favorite movie
| * e6c65a6 Add new sidebar content
* | e014d91 (footer) Add links to social media
* | 209752a Improve site heading for SEO
* | 3772ab1 Set background color for page
|/  
* 5bfe5e7 Add starting HTML structure
* 6fa5f34 Add .gitignore file
* a879849 Add header to blog
* 94de470 Initial commit

我们来看看如何引用一些之前的 commit。因为 HEAD 指向 9ec05ca commit:

  • HEAD^db7e87a commit
  • HEAD~1 同样是 db7e87a commit
  • HEAD^^796ddb0 commit
  • HEAD~2 同样是 796ddb0 commit
  • HEAD^^^0c5975a commit
  • HEAD~3 同样是 0c5975a commit
  • HEAD^^^24c9749e commit(这是曾祖父的 (HEAD^^) 第二个父 commit (^2))

HEAD~4 引用的是当前分支的第四个父 commit,然后 ^2 告诉我们它是合并 commit 的第二个父 commit(被合并的那个 commit !)。

git reset 命令

git reset 命令用来重置(清除)commit

$ git reset <reference-to-commit>

可以用来:

  • 将 HEAD 和当前分支指针移到目标 commit
  • 清除 commit
  • 将 commit 的更改移到暂存区
  • 取消暂存 commit 的更改

git reset 的选项

git 根据所使用选项来判断是清除暂存之前 commit 的更改,还是取消暂存之前 commit 的更改。这些选项包括:

  • --mixed
  • --soft
  • --hard

理解这些选项的工作方式:

Git命令(撤销更改)

这是我们仓库的三个部分:工作区、暂存区和顶部的版本库。master 当前指向最近的提交,HEAD 当前指向 master

Git命令(撤销更改)

让我们转换一下布局,运行 reset 后,提交内容可能会去三个地方 工作区、暂存区或回收站,去回收站表示它将被删除。

Git命令(撤销更改)

运行 git reset HEAD~1 会将 HEADmaster 移动到前一个提交。这个带 3 的提交所做的更改可能移动到工作区或暂存区,也可能直接被移到回收站,这完全取决于 reset 命令一起使用的选项。如果不指定任何选项的来运行 git reset,将留存在工作区的文件中,这是因为 --mixed 是默认值。如果我们暂存文件并在此提交,将会获得相同的提交内容。但我们会得到一个不同的提交 SHA,这是因为提交的时间戳与原来的时间戳不同,但提交内容将完全一样。

Git命令(撤销更改)

如果使用 --soft 选项,会将 SHA 为 3 的提交中所作的更改移动到暂存区,这些更改冉冉相同,而且已经暂存好了,我们要做的只是运行 git commit 来重新提交,同样由于时间戳不同,所以新提交的 SHA 也会不同。

Git命令(撤销更改)

--hard 选项,它会删除 SHA 为 3 的提交中所作的所有更改。

备份分支

在进行任何重置操作之前,我通常会在最近的 commit 上创建一个 backup 分支,因此如果出现错误,我可以返回这些 commit:

$ git branch backup

如果你在重置任何内容前创建了 backup 分支,那么你可以轻松地让 master 分支指向 backup 分支所指向的同一 commit。你只需:

  • 从工作目录中删除未 commit 的更改
  • backup 合并到 master(这将导致快进合并并使 master 向上移到和 backup 一样的点)

Git 文档的 git-reset

相关标签: Git命令