git reset --mixed、--soft 和 --hard 之间有什么区别?
我正在寻找拆分提交,但不确定要使用哪个重置选项。
我正在查看页面 用简单的英语来说,什么是“git重置”做什么?,但我意识到我并不真正理解git索引或暂存区域是什么,因此解释没有帮助。
另外,在该答案中, --mixed
和 --soft
的用例在我看来是相同的(当您想要修复并重新提交时)。有人可以进一步分解吗?我意识到 --mixed
可能是可以选择的选项,但我想知道为什么。最后,--hard
怎么样?
有人能给我一个工作流程示例,说明如何选择这 3 个选项吗?
I'm looking to split a commit up and not sure which reset option to use.
I was looking at the page In plain English, what does "git reset" do?, but I realized I don't really understand what the git index or staging area is and thus the explanations didn't help.
Also, the use cases for --mixed
and --soft
look the same to me in that answer (when you want to fix and recommit). Can someone break it down even more? I realize --mixed
is probably the option to go with, but I want to know why. Lastly, what about --hard
?
Can someone give me a workflow example of how selecting the 3 options would happen?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
当您修改存储库中的文件时,更改最初不会暂存。为了提交它,您必须使用
git add
将其暂存(即将其添加到索引中)。当您进行提交时,提交的更改是已添加到索引中的更改。1git reset
至少更改当前分支 2 正在指向。--mixed
和--soft
之间的区别在于您的索引是否也被修改。因此,如果我们在分支master
上进行这一系列提交:HEAD
(当前提交)是C
3 并且索引与C
匹配(假设我们没有使用git add
进行任何更改)。当我们运行 git reset --soft B 时,master(以及间接的 HEAD)现在指向 B ,但索引仍然有
C
的变化;git status
会将它们显示为已上演。因此,如果我们此时运行git commit
,我们将获得一个新的提交,其更改与C
相同。(如果我们在重置之前确实进行了暂存更改,那么这些更改仍将位于索引中,并且除了来自
C
的更改之外,git commit
还会提交这些更改。)好的,所以再次从这里开始:
现在让我们执行 git reset --mixed B 。 (
--mixed
是默认选项,因此这相当于git reset B
)。master
和HEAD
再次指向B
,但这次索引也被修改以匹配B
。如果我们此时运行 git commit ,则不会发生任何事情,因为索引与 HEAD 匹配。我们在工作目录中仍然有更改,但由于它们不在索引中,因此git status
将它们显示为未暂存。要提交它们,您需要git add
,然后照常提交。(这一次,如果我们在重置之前进行了暂存更改,这些更改将从索引中删除,但文件本身仍将包含所做的任何更改。)
最后,
--hard
是与--mixed
相同(它会更改您的HEAD
和索引),但--hard
也会修改您的工作目录。如果我们在C
并运行git reset --hard B
,那么在C
中添加的更改以及任何您所做的未提交的更改将被删除,并且工作副本中的文件将与提交B
匹配。由于这种方式可能会永久丢失更改,因此在进行硬重置之前,您应该始终运行 git status ,以确保您的工作目录是干净的,或者您可以接受丢失未提交的更改。在上述每种情况下,我们都指定了要重置的提交 (
B
)。如果您不提供,它将使用HEAD
作为默认值。未指定提交的 git reset --soft 不会执行任何操作(它使当前分支指向它已经指向的位置),但它对于其他两种模式很有用。git reset --mixed
(或只是git reset
)更新索引以匹配当前提交,这具有取消暂存已添加但未提交的任何更改的效果; git reset --hard 执行相同的操作,此外它还会删除工作目录中的所有更改,以便所有文件都与当前分支上的最新提交相匹配。 (同样,由于这些更改将永久丢失,因此在进行硬重置时应小心。)1 索引也称为“暂存区域”。您可以将其视为存储库中所有文件的另一个副本。当检出分支时,索引会更新,以便其所有文件都与该分支的内容匹配。当您
git add
文件时,对该文件所做的任何更改都会复制到索引中,当您git commit
时,索引的内容将变成提交并添加到当前分支。2
HEAD
是 Git 引用当前签出的提交的方式。HEAD
(在大多数情况下)指向一个特定的分支,称为当前分支,并且该分支指向一个特定的提交。3 因为
HEAD
指向master
,而master
指向C
。每当我们在当前分支上添加或删除提交时,HEAD
引用的提交发生变化并不是因为HEAD
本身发生了变化,而是因为HEAD
所在的分支发生了变化。 code> 指向已更新为指向该提交。When you modify a file in your repository, the change is initially unstaged. In order to commit it, you must stage it—that is, add it to the index—using
git add
. When you make a commit, the changes that are committed are those that have been added to the index.1git reset
changes, at minimum, where the current branch2 is pointing. The difference between--mixed
and--soft
is whether or not your index is also modified. So, if we're on branchmaster
with this series of commits:HEAD
(the current commit) isC
3 and the index matchesC
(assuming we haven't staged any changes withgit add
).When we run
git reset --soft B
,master
(and thusHEAD
, indirectly) now points toB
, but the index still has the changes fromC
;git status
will show them as staged. So if we rungit commit
at this point, we'll get a new commit with the same changes asC
.(If we did have staged changes before the reset, those will still be in the index and
git commit
would commit those changes in addition to the changes fromC
.)Okay, so starting from here again:
Now let's do
git reset --mixed B
. (--mixed
is the default option, so this is equivalent togit reset B
). Once again,master
andHEAD
point toB
, but this time the index is also modified to matchB
. If we rungit commit
at this point, nothing will happen since the index matchesHEAD
. We still have the changes in the working directory, but since they're not in the index,git status
shows them as unstaged. To commit them, you wouldgit add
and then commit as usual.(This time, if we had staged changes before the reset, those changes will be removed from the index, but the files themselves will still contain any changes that were made.)
And finally,
--hard
is the same as--mixed
(it changes yourHEAD
and index), except that--hard
also modifies your working directory. If we're atC
and rungit reset --hard B
, then the changes added inC
, as well as any uncommitted changes you've made, will be removed, and the files in your working copy will match commitB
. Since you can permanently lose changes this way, you should always rungit status
before doing a hard reset to make sure your working directory is clean or that you're okay with losing your uncommitted changes.In each of the above cases, we specified a commit (
B
) to reset to. If you don't provide one, it usesHEAD
as the default.git reset --soft
with no commit specified doesn't do anything (it makes the current branch point to where it was already pointing), but it can be useful for the other two modes.git reset --mixed
(or justgit reset
) updates the index to match the current commit, which has the effect of unstaging any changes that have been added but not committed;git reset --hard
does the same, plus it removes any changes in your working directory so that all your files match the latest commit on your current branch. (Again, since those changes are permanently lost, you should be careful when doing a hard reset.)1 The index is also referred to as the "staging area". You can think of it as another copy of all the files in the repository. When a branch is checked out, the index is updated so that all its files match the contents of that branch. When you
git add
a file, any changes you made to that file are copied to the index, and when yougit commit
, the contents of the index are turned into a commit and added to the current branch.2
HEAD
is how Git refers to the commit that is currently checked out.HEAD
(in most cases) points to a specific branch, called the current branch, and that branch points to a specific commit.3 Because
HEAD
points tomaster
andmaster
points toC
. Whenever we add or remove a commit on the current branch, the commit thatHEAD
refers to changes not becauseHEAD
itself changed, but because the branch thatHEAD
points to was updated to point to that commit.用最简单的术语来说:
--soft
:取消提交更改,更改暂存(索引)。--mixed
(默认):取消提交 + 取消暂存更改,更改保留在工作树中< /em>。--hard
:取消提交+取消暂存+删除更改,没有留下任何内容。In the simplest terms:
--soft
: uncommit changes, changes are left staged (index).--mixed
(default): uncommit + unstage changes, changes are left in working tree.--hard
: uncommit + unstage + delete changes, nothing left.三种类型的遗憾
很多现有的答案似乎并没有回答实际的问题。它们是关于命令的作用,而不是关于您(用户)想要什么 - 用例。但这就是OP所问的!
根据您在发出 git reset 命令时所后悔的事情来描述可能会更有帮助。假设我们有这样的情况:
以下是一些可能的遗憾以及如何处理它们:
1. 我很遗憾 B、C 和 D 不是一个提交。
git reset --soft A
。我现在可以立即提交并立即完成,自 A 以来的所有更改都是一次提交。2. 我很遗憾 B、C 和 D 不是两次 次提交(或十次 次提交,或其他)。
git reset --mixed A。提交消失了,索引又回到了 A,但是工作区看起来仍然和 D 之后一样。所以现在我可以在一个完全不同的分组中添加和提交。
3. 我很遗憾 B、C 和 D 发生在这个分支上;我希望我在 A 之后分支,而它们发生在另一个分支上。
创建一个新分支
otherbranch
,然后git reset --hard A
。当前分支现在以 A 结束,otherbranch
源于它并包含 B、C 和 D。(当然,您也可以使用硬重置,因为您希望 B、C 和 D 从未发生过)根本就发生过。)
Three types of regret
A lot of the existing answers don't seem to answer the actual question. They are about what the commands do, not about what you (the user) want — the use case. But that is what the OP asked about!
It might be more helpful to couch the description in terms of what it is precisely that you regret at the time you give a
git reset
command. Let's say we have this:Here are some possible regrets and what to do about them:
1. I regret that B, C, and D are not one commit.
git reset --soft A
. I can now immediately commit and presto, all the changes since A are one commit.2. I regret that B, C, and D are not two commits (or ten commits, or whatever).
git reset --mixed A
. The commits are gone and the index is back at A, but the work area still looks as it did after D. So now I can add-and-commit in a whole different grouping.3. I regret that B, C, and D happened on this branch; I wish I had branched after A and they had happened on that other branch.
Make a new branch
otherbranch
, and thengit reset --hard A
. The current branch now ends at A, withotherbranch
stemming from it and containing B, C, and D.(Of course you could also use a hard reset because you wish B, C, and D had never happened at all.)
请注意,这是一个简化的解释,旨在作为理解这一复杂功能的第一步。
对于想要在每个命令之后可视化其项目状态的视觉学习者可能会有所帮助:
给定:
- A - B - C (master)
对于那些使用打开颜色的终端的人
(git config --global color.ui auto):
git reset --soft A
,您将看到 B 和 C 的内容呈绿色(已暂存并准备提交)git reset --mixed A
(或git reset A
),您将看到 B 和 C 的内容呈红色(未暂存并准备好暂存(绿色),然后提交)git reset --hard A
并且您将不再在任何地方看到 B 和 C 的更改(就好像它们从未存在过一样)或者对于那些使用“Tower”或“SourceTree”等 GUI 程序的人
git reset --soft A
,您将在“暂存文件”区域中看到 B 和 C 的内容,准备提交git reset --mixed A
(或git reset A
),然后您将在“未暂存文件”区域中看到 B 和 C 的内容,准备移动到暂存,然后提交git reset --hard A
并且您将不再在任何地方看到 B 和 C 的更改(将像如果它们从未存在过)Please be aware, this is a simplified explanation intended as a first step in seeking to understand this complex functionality.
May be helpful for visual learners who want to visualise what their project state looks like after each of these commands:
Given:
- A - B - C (master)
For those who use Terminal with colour turned on
(git config --global color.ui auto):
git reset --soft A
and you will see B and C's stuff in green (staged and ready to commit)git reset --mixed A
(orgit reset A
) and you will see B and C's stuff in red (unstaged and ready to be staged (green) and then committed)git reset --hard A
and you will no longer see B and C's changes anywhere (will be as if they never existed)Or for those who use a GUI program like 'Tower' or 'SourceTree'
git reset --soft A
and you will see B and C's stuff in the 'staged files' area ready to commitgit reset --mixed A
(orgit reset A
) and you will see B and C's stuff in the 'unstaged files' area ready to be moved to staged and then committedgit reset --hard A
and you will no longer see B and C's changes anywhere (will be as if they never existed)所有其他答案都很棒,但我发现最好通过将文件分为三类来理解它们:
unstaged
、staged
、commit
:--hard
应该很容易理解,它恢复了所有--mixed
(默认) :未暂存
文件:不更改已暂存
文件:移至未暂存
提交
文件:移至未暂存
--soft
:未暂存
文件:不更改暂存
文件:不要更改提交
文件:移至暂存
总之:
--soft
选项会将所有内容(unstaged
文件除外)移动到staging 区域
--mixed
选项会将所有内容移至未暂存区域
All the other answers are great, but I find it best to understand them by breaking down files into three categories:
unstaged
,staged
,commit
:--hard
should be easy to understand, it restores everything--mixed
(default) :unstaged
files: don't changestaged
files: move tounstaged
commit
files: move tounstaged
--soft
:unstaged
files: don't changestaged
files: dont' changecommit
files: move tostaged
In summary:
--soft
option will move everything (exceptunstaged
files) intostaging area
--mixed
option will move everything intounstaged area
在这些情况下,我喜欢一个能够解释这一点的视觉效果:
git reset --[hard/mixed/soft]
:所以每一个都会影响不同的范围:
In these cases I like a visual that can hopefully explain this:
git reset --[hard/mixed/soft]
:So each one affects different scopes:
您不必强迫自己记住它们之间的差异。想想你实际上是如何做出承诺的。
进行一些更改。
git add .
git commit -m "我做了某事"
Soft、Mixed 和 Hard 是让你放弃从 3 到 1 所做的操作的方法。
git commit
。git add 。
You don't have to force yourself to remember differences between them. Think of how you actually made a commit.
Make some changes.
git add .
git commit -m "I did Something"
Soft, Mixed and Hard is the way enabling you to give up the operations you did from 3 to 1.
git commit
.git add .
这里是对 TortoiseGit 用户的基本解释:
git reset --soft
和--mixed
保持文件不变。git reset --hard
实际上更改您的文件以匹配您重置的提交。在TortoiseGit中,索引的概念被GUI隐藏得很深。当您修改文件时,无需运行 git add 即可将更改添加到暂存区/索引。当简单地处理对现有文件的修改而不改变文件名时,
git reset --soft
和--mixed
是相同的!仅当添加新文件或重命名文件时,您才会注意到差异。在这种情况下,如果运行 git reset --mixed,则必须从“非版本化文件”列表中重新添加文件。Here is a basic explanation for TortoiseGit users:
git reset --soft
and--mixed
leave your files untouched.git reset --hard
actually change your files to match the commit you reset to.In TortoiseGit, The concept of the index is very hidden by the GUI. When you modify a file, you don't have to run
git add
to add the change to the staging area/index. When simply dealing with modifications to existing files that are not changing file names,git reset --soft
and--mixed
are the same! You will only notice a difference if you added new files or renamed files. In this case, if you run git reset --mixed, you will have to re-add your file(s) from the Not Versioned Files list.mkarasek 的答案很棒,简单来说我们可以说...
git reset --soft
:将HEAD
设置为预期的提交,但保留上次提交的更改git reset --soft
相同,但唯一的区别是它取消了上次提交的更改git reset --hard
code> :在您指定的提交上设置您的HEAD
,并重置上次提交的所有更改,包括未提交的更改。mkarasek's Answer is great, in simple terms we can say...
git reset --soft
: set theHEAD
to the intended commit but keep your changes staged from last commitsgit reset --mixed
: it's same asgit reset --soft
but the only difference is it un stage your changes from last commitsgit reset --hard
: set yourHEAD
on the commit you specify and reset all your changes from last commits including un committed changes.在讨论这三个选项之前,必须了解三件事。
1) 历史记录/HEAD
2) 阶段/索引
3) 工作目录
重置 --soft : 历史记录已更改,HEAD 已更改,工作目录未更改。
reset --mixed :历史记录已更改,HEAD 已更改,工作目录已更改为未暂存的数据。
reset --hard :历史记录已更改,HEAD 已更改,工作目录已更改并丢失了数据。
使用 Git --soft 总是安全的。在复杂的需求中应该使用其他选项。
Before going into these three option one must understand 3 things.
1) History/HEAD
2) Stage/index
3) Working directory
reset --soft : History changed, HEAD changed, Working directory is not changed.
reset --mixed : History changed, HEAD changed, Working directory changed with unstaged data.
reset --hard : History changed, HEAD changed, Working directory is changed with lost data.
It is always safe to go with Git --soft. One should use other option in complex requirement.
这里有很多答案对 git reset --soft 存在误解。虽然在特定条件下 git reset --soft 只会更改 HEAD(从分离的头状态开始),但通常(并且为了预期用途),< strong>它会移动您当前签出的分支引用。当然,如果您没有签出分支,它就无法执行此操作(因此特定条件
git reset --soft< /code> 只会更改
HEAD
)。我发现这是考虑 git reset 的最佳方式。您不只是移动
HEAD
(一切都这样做),您还移动了分支引用,例如master
。这与运行 git commit 时发生的情况类似(当前分支与 HEAD 一起移动),只不过不是创建(并移动到)一个新的 /em> 提交,您将移至先前 提交。这是
重置
的要点,将分支更改为新提交以外的内容,而不是更改HEAD
。您可以在文档示例中看到这一点:这一系列命令有什么意义呢?您想要移动一个分支,这里是
master
,因此当您签出master
时,您可以运行git reset
。这里投票最高的答案通常是好的,但我想我应该添加这个来纠正几个带有误解的答案。
更改分支
git reset --soft
:将当前签出分支的分支指针重置为指定引用处的提交。工作目录和索引中的文件不会更改。从这个阶段提交将带您回到执行 git reset 命令之前的位置。
也更改索引
git reset --mixed
或等效
git reset
:执行
--soft
的操作 < strong>AND 还将索引重置为与指定引用处的提交匹配。虽然 git reset --soft HEAD 不执行任何操作(因为它表示将已签出的分支移动到已签出的分支),但 git reset --mixed HEAD 或等效的>git reset HEAD
是一个常见且有用的命令,因为它将索引重置为上次提交的状态。也更改您的工作目录
git reset --hard
:执行--mixed
的操作并且还会覆盖您的工作目录。此命令类似于 git checkout,不同之处在于(这是关于reset
的关键点)所有形式的git reset< /code> 移动
HEAD
指向的分支。关于“某某命令移动 HEAD”的注释:
说命令移动
HEAD 是没有用的
。任何更改您在提交历史记录中的位置的命令都会移动HEAD
。这就是HEAD
的意义,一个指向你所在位置的指针。HEAD
就是你,因此无论你何时移动,它都会移动。There are a number of answers here with a misconception about
git reset --soft
. While there is a specific condition in whichgit reset --soft
will only changeHEAD
(starting from a detached head state), typically (and for the intended use), it moves the branch reference you currently have checked out. Of course it can't do this if you don't have a branch checked out (hence the specific condition wheregit reset --soft
will only changeHEAD
).I've found this to be the best way to think about
git reset
. You're not just movingHEAD
(everything does that), you're also moving the branch ref, e.g.,master
. This is similar to what happens when you rungit commit
(the current branch moves along withHEAD
), except instead of creating (and moving to) a new commit, you move to a prior commit.This is the point of
reset
, changing a branch to something other than a new commit, not changingHEAD
. You can see this in the documentation example:What's the point of this series of commands? You want to move a branch, here
master
, so while you havemaster
checked out, you rungit reset
.The top voted answer here is generally good, but I thought I'd add this to correct the several answers with misconceptions.
Change your branch
git reset --soft <ref>
: resets the branch pointer for the currently checked out branch to the commit at the specified reference,<ref>
. Files in your working directory and index are not changed. Committing from this stage will take you right back to where you were before thegit reset
command.Change your index too
git reset --mixed <ref>
or equivalently
git reset <ref>
:Does what
--soft
does AND also resets the index to the match the commit at the specified reference. Whilegit reset --soft HEAD
does nothing (because it says move the checked out branch to the checked out branch),git reset --mixed HEAD
, or equivalentlygit reset HEAD
, is a common and useful command because it resets the index to the state of your last commit.Change your working directory too
git reset --hard <ref>
: does what--mixed
does AND also overwrites your working directory. This command is similar togit checkout <ref>
, except that (and this is the crucial point aboutreset
) all forms ofgit reset
move the branch refHEAD
is pointing to.A note about "such and such command moves the HEAD":
It is not useful to say a command moves the
HEAD
. Any command that changes where you are in your commit history moves theHEAD
. That's what theHEAD
is, a pointer to wherever you are.HEAD
is you, and so will move whenever you do.--mixed vs --soft vs --hard:
注意: 如果提交已确认到本地存储库并放弃这些提交,我们可以使用:
但是如果提交已确认到远程存储库,则不建议使用重置命令,我们必须使用
revert命令
来放弃远程提交。--mixed vs --soft vs --hard:
NOTE: If the commits are confirmed to the local repository and to discard those commits we can use:
But if the commits are confirmed to the remote repository then not recommended to use the reset command and we have to use the
revert command
to discard the remote commits.简短回答在什么情况下使用这 3 个选项:
保留代码中的当前更改,但重写提交历史记录:
软
:您可以一次提交所有内容,然后使用新的描述创建一个新的提交(如果您使用 torotise git 或任何其他大多数 GUI,则可以使用这个,因为您仍然可以在提交中勾选您想要的文件,并以这种方式对不同的文件进行多次提交。 Sourcetree 中的所有文件都将暂存以供提交。)混合
:在提交之前,您必须将各个文件再次添加到索引中(在 Sourcetree 中,所有更改的文件都将取消暂存)实际上 也会丢失代码中的更改:
硬
:您不仅会重写历史记录,还会丢失重置点之前的所有更改A short answer in what context the 3 options are used:
To keep the current changes in the code but to rewrite the commit history:
soft
: You can commit everything at once and create a new commit with a new description (if you use torotise git or any most other GUIs, this is the one to use, as you can still tick which files you want in the commit and make multiple commits that way with different files. In Sourcetree all files would be staged for commit.)mixed
: You will have to add the individual files again to the index before you make commits (in Sourcetree all the changed files would be unstaged)To actually lose your changes in the code as well:
hard
: you don't just rewrite history but also lose all your changes up to the point you resetgit reset 命令各个选项之间的基本区别如下。
Basic difference between various options of git reset command are as below.
--soft
:告诉 Git 将 HEAD 重置为另一个提交,因此索引和工作目录不会以任何方式更改。在原始 HEAD 和提交之间更改的所有文件都将被暂存。--mixed
:就像软件一样,这会将 HEAD 重置为另一个提交。它还将重置索引以匹配它,同时工作目录不会被触及。所有更改都将保留在工作目录中并显示为已修改,但未暂存。--hard
:这会重置所有内容 - 它将 HEAD 重置回另一个提交,重置索引以匹配它,并重置工作目录以匹配它。--mixed
和--soft
之间的主要区别在于您的索引是否也被修改。 此处查看更多相关信息。--soft
: Tells Git to reset HEAD to another commit, so index and the working directory will not be altered in any way. All of the files changed between the original HEAD and the commit will be staged.--mixed
: Just like the soft, this will reset HEAD to another commit. It will also reset the index to match it while working directory will not be touched. All the changes will stay in the working directory and appear as modified, but not staged.--hard
: This resets everything - it resets HEAD back to another commit, resets the index to match it, and resets the working directory to match it as well.The main difference between
--mixed
and--soft
is whether or not your index is also modified. Check more about this here.git reset --soft
将从存储库中删除的提交中的更改移动到索引中,并合并到已经存在的任何内容中。git reset --hard
会丢失工作树和索引中的更改。它是唯一改变工作树的。
git reset --soft <B>
moves the changes from commits removed from repo into the index, merging in any that were there already.git reset --hard <b>
loses the changes in the working tree and the index.It is the only one to change the working tree.
莫阿里用最简单的术语来说,这是另一个简单的解释:
--soft
:重置 HEAD 指针到先前的提交--mixed
:< code>--soft + 删除添加
更改--hard
:--mixed
+ 恢复工作树文件更改(小心!)Mo Ali has put it in simplest terms and here's another simple explanation:
--soft
: reset HEAD pointer to previous commit--mixed
:--soft
+ deleteadd
ed changes--hard
:--mixed
+ recover working tree file changes (CAREFUL!)公共信息
这三个选项
--soft
、--mixed
和--hard
共享公共信息,例如:分支
和HEAD
同时,而不仅仅是特定commit hash
的HEAD
commit hash
不存在时指定,HEAD
是默认值reflog
和reset
来恢复命令以返回到原始commitHEAD
之前处于的代码>--soft
工作目录
Staging
中的文件执行任何操作>HEAD
和commit hash
之间发生的修改被移至Staging
--mixed
工作目录
Staging
中的所有文件都将从Staging
中删除并移至工作目录
就像您执行了
git Restore --staged
一样,HEAD
和commit hash
之间发生的修改不会移至Staging
--mixed
是git reset
的默认值我们可以说
--mixed
等于--soft
> 但是:git add
Staging
删除到工作目录
有趣的事实:执行
--mixed
后在git status
中看到,当我们执行git add .
后,我们会得到相同的git status
code> 就好像我们执行了--soft
--hard
--hard
是危险的,应该谨慎使用,因为:HEAD
到提交哈希
并强制对工作目录
进行更改工作目录
中的任何修改,而无法恢复它们< br>也就是说,它会丢弃
修改的文件
,Staging
中的任何文件注意:谨防使用
--hard 因为它将影响
工作目录
并强制它匹配指定的提交
并且
工作目录
中的任何修改文件
都将被丢弃因此,在使用
git reset --hard
之前并且如果当前有文件正在修改在工作目录
中,您应该在执行git reset --hard
之前将这些修改移到其他地方。这就是 git stash 发挥作用的地方,它可以帮助您总结软、混合和硬之间的差异
暂存区域
暂存区域
工作目录
中的原样工作目录
工作目录
中的原样工作目录
与指定中的版本匹配commit
Common Info
The three options
--soft
,--mixed
and--hard
share common info like:branch
andHEAD
simultaneously, not just theHEAD
to the specificcommit hash
commit hash
is not specified, theHEAD
is being the defaultreflog
andreset
to return to the originalcommit
that theHEAD
was on before--soft
Working Directory
Staging
HEAD
andcommit hash
are moved to theStaging
--mixed
Working Directory
Staging
are removed from theStaging
and moved to theWorking Directory
as if you performed
git restore --staged
HEAD
andcommit hash
are not moved to theStaging
--mixed
is the default value forgit reset
We can say that
--mixed
equals--soft
but:git add
Staging
to theWorking Directory
Fun fact: What you see in
git status
after executing--mixed
, after we performgit add .
, we will get the samegit status
as if we executed--soft
--hard
--hard
is dangerous and should be used with caution because:HEAD
to thecommit hash
and forced the changes on theWorking Directory
Working Directory
without a way to recover themmeaning, it discards the
Modified Files
Staging
Note: Beware of using
--hard
as it will affect theWorking Directory
and force it matchs the specifiedcommit
And any
Modified Files
in theWorking Directory
will be discardedSo, before using
git reset --hard
and if there are files currently being modified in theWorking Directory
, you should move these modifications elsewhere before executinggit reset --hard
. This is wheregit stash
comes in and help youSummarizing the differences between soft, mixed, and hard
Staging Area
Staging Area
Working Directory
Working Directory
Working Directory
Working Directory
match the version it was in the specifiedcommit
我不是 git 专家,只是来到这个论坛来了解它!因此,也许我的解释并不完美,对此表示抱歉。我发现所有其他答案都有帮助,我将尝试提供另一个观点。我会稍微修改一下这个问题,因为我猜这可能是作者的意图:“我是 git 的新手。在使用 git 之前,当我执行重大更改时,我会像这样重命名我的文件:main.c、main_1.c、main_2.c,以便在出现问题时能够返回。因此,如果我决定返回 main_1.c,这很容易,而且我还保留了 main_2.c 和 main_3.c,因为稍后我也可能需要它们。我如何使用 git 轻松完成同样的事情?”
对于我的回答,我主要使用上面 Matt 的精彩回答中的“遗憾之三”,因为我也认为最初的问题是“如果我在使用 git 时感到遗憾,我该怎么办?”。一开始的情况是这样的:
ABCD(master)
ABCD(master 和 mynewbranch)
Git reset --hard thenumberofthecommitA
或
Git reset --hard master~3
然后得到:
A (master) – B – C – D (mynewbranch)
然后,可以继续工作并从 A (master) 提交,但仍然可以通过签出其他分支来轻松访问其他版本:git查看 mynewbranch。
现在,让我们想象一下,在命令 git reset --hard 之前忘记创建一个新分支。提交 B、C、D 是否丢失了?没有,但没有存储在任何分支中。要再次找到它们,可以使用命令:git reflog,该命令被视为“安全命令”(“如果出现麻烦,请保持冷静并使用 git reflog”)。此命令将列出所有提交,甚至包括那些不属于任何分支的提交。因此,这是查找提交 B、C 或 D 的便捷方法。
I’m not a git expert and just arrived on this forum to understand it! Thus maybe my explanation is not perfect, sorry for that. I found all the other answer helpful and I will just try to give another perspective. I will modify a bit the question since I guess that it was maybe the intent of the author: “I’m new to git. Before using git, I was renaming my files like this: main.c, main_1.c, main_2.c when i was performing majors changes in order to be able to go back in case of trouble. Thus, if I decided to come back to main_1.c, it was easy and I also keep main_2.c and main_3.c since I could also need them later. How can I easily do the same thing using git?”
For my answer, I mainly use the “regret number three” of the great answer of Matt above because I also think that the initial question is about “what do I do if I have regret when using git?”. At the beginning, the situation is like that:
A-B-C-D (master)
A-B-C-D (master and mynewbranch)
Git reset --hard thenumberofthecommitA
or
Git reset --hard master~3
Then one obtains:
A (master) – B – C – D (mynewbranch)
Then, it’s possible to continue working and commit from A (master) but still can get an easy access to the other versions by checking out on the other branch: git checkout mynewbranch.
Now, let’s imagine that one forgot to create a new branch before the command git reset --hard. Is the commit B, C, D are lost? No, but there are not stored in any branches. To find them again, one may use the command : git reflog that is consider as “a safety command”( “in case of trouble, keep calm and use git reflog”). This command will list all commits even those that not belong to any branches. Thus, it’s a convenient way to find the commit B, C or D.