git reset
确实知道五种“模式”:软、混合、硬、合并和保留。我将从前三种开始,因为这些是您通常会遇到的模式。之后你会发现一个不错的小奖励,所以请继续关注。
假设您有一个具有类似于以下历史记录的存储库:
7e05a95 (HEAD -> main) Update a
e62add5 Update b
ca9ae0a Update a
9b6060d Add c
eebe372 Add b
947586a Add a
其中最新提交(7e05a95
) 包含这些更改:
diff --git a/a b/a
index b66ba06..28b68e2 100644
--- a/a
+++ b/a
@@ -1 +1 @@
-new content
+new new content
现在当你跑步时会发生什么git reset
与各种不同的模式?让我们来看看吧!
soft
使用时git reset --soft HEAD~1
您将从当前分支中删除最后一次提交,但文件更改将保留在您的工作树 https://craftquest.io/articles/what-is-the-working-tree-in-git。此外,更改将保留在您的索引中,因此以下是git commit
将创建一个与您之前“删除”的提交具有完全相同更改的提交。
这在实践中会是什么样子?像这样:
> git reset --soft HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: a
正如您看到文件中的更改a
已在索引上,并准备再次提交。
mixed
这是默认模式,与软模式非常相似。当“删除”提交时git reset HEAD~1
您仍会将更改保留在工作树中,但不会保留在索引中;因此,如果您想“重做”提交,则必须添加更改(git add
)在提交之前。
实际上,结果可能如下所示:
> git reset --mixed HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a
no changes added to commit (use "git add" and/or "git commit -a")
文件的变化a
仍然存在,但不在索引中。
hard
使用时git reset --hard HEAD~1
你会丢失所有未提交的更改和所有未跟踪的文件除了上次提交中引入的更改之外。这些更改不会保留在您的工作树中,因此git status
命令将告诉您存储库中没有任何更改。
小心对待这个。如果您不小心删除了从未跟踪过的未提交的更改git
(说:已提交或至少添加到索引中),您无法使用git
.
一个实际的例子可能如下所示:
> git reset --hard HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
nothing to commit, working tree clean
如您所见,没有任何变化。假设您在文件中还有一些未提交的更改b
这些也会丢失!
> echo 'some uncommitted changes' > b
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: b
no changes added to commit (use "git add" and/or "git commit -a")
> git reset --hard HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
nothing to commit, working tree clean
Bonus
keep
git reset --keep HEAD~1
是一个有趣且有用的。它仅重置之间不同的文件current HEAD
和给定的提交。如果其中一个或多个文件有未提交的更改,它会中止重置。它基本上充当一个更安全的版本hard
.
让我们回顾一下之前的示例,其中您有一些未提交的更改b
:
> echo 'some uncommitted changes' > b
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: b
no changes added to commit (use "git add" and/or "git commit -a")
> git reset --keep HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: b
no changes added to commit (use "git add" and/or "git commit -a")
您删除了文件中的更改a
但保留了文件中未提交的更改b
!
所以重申一下:“硬”将消除all更改,而“keep”仅从重置提交中删除更改。
这些模式中的每一种都在git 重置文档 http://git-scm.com/docs/git-reset.
Note
做的时候git reset
要删除提交,该提交并没有真正丢失,只是没有指向它或其任何子项的引用。您仍然可以恢复已“删除”的提交git reset
通过查找它的 SHA-1 密钥,例如使用以下命令git reflog
.