git reset --mixed、--soft 和 --hard 之间有什么区别?

发布于 2024-09-14 20:06:46 字数 433 浏览 5 评论 0原文

我正在寻找拆分提交,但不确定要使用哪个重置选项。

我正在查看页面 用简单的英语来说,什么是“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

魄砕の薆 2024-09-21 20:06:46

当您修改存储库中的文件时,更改最初不会暂存。为了提交它,您必须使用 git add 将其暂存(即将其添加到索引中)。当您进行提交时,提交的更改是已添加到索引中的更改。1

git reset 至少更改当前分支 2 正在指向。 --mixed--soft 之间的区别在于您的索引是否也被修改。因此,如果我们在分支 master 上进行这一系列提交:

- A - B - C (master)

HEAD(当前提交)是 C3 并且索引与 C 匹配(假设我们没有使用 git add 进行任何更改)。

当我们运行 git reset --soft B 时,master(以及间接的 HEAD)现在指向 B ,但索引仍然有 C 的变化; git status 会将它们显示为已上演。因此,如果我们此时运行 git commit,我们将获得一个新的提交,其更改与 C 相同。

(如果我们在重置之前确实进行了暂存更改,那么这些更改仍将位于索引中,并且除了来自 C 的更改之外,git commit 还会提交这些更改。)


好的,所以再次从这里开始:

- A - B - C (master)

现在让我们执行 git reset --mixed B 。 (--mixed 是默认选项,因此这相当于 git reset B)。 masterHEAD 再次指向 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.1

git 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 branch master with this series of commits:

- A - B - C (master)

HEAD (the current commit) is C3 and the index matches C (assuming we haven't staged any changes with git add).

When we run git reset --soft B, master (and thus HEAD, indirectly) now points to B, but the index still has the changes from C; git status will show them as staged. So if we run git commit at this point, we'll get a new commit with the same changes as C.

(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 from C.)


Okay, so starting from here again:

- A - B - C (master)

Now let's do git reset --mixed B. (--mixed is the default option, so this is equivalent to git reset B). Once again, master and HEAD point to B, but this time the index is also modified to match B. If we run git commit at this point, nothing will happen since the index matches HEAD. 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 would git 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 your HEAD and index), except that --hard also modifies your working directory. If we're at C and run git reset --hard B, then the changes added in C, as well as any uncommitted changes you've made, will be removed, and the files in your working copy will match commit B. Since you can permanently lose changes this way, you should always run git 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 uses HEAD 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 just git 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 you git 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 to master and master points to C. Whenever we add or remove a commit on the current branch, the commit that HEAD refers to changes not because HEAD itself changed, but because the branch that HEAD points to was updated to point to that commit.

拿命拼未来 2024-09-21 20:06:46

用最简单的术语来说:

  • --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.
风铃鹿 2024-09-21 20:06:46

三种类型的遗憾

很多现有的答案似乎并没有回答实际的问题。它们是关于命令的作用,而不是关于您(用户)想要什么 - 用例。但这就是OP所问的!

根据您在发出 git reset 命令时所后悔的事情来描述可能会更有帮助。假设我们有这样的情况:

A - B - C - D <- HEAD

以下是一些可能的遗憾以及如何处理它们:

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:

A - B - C - D <- HEAD

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 then git reset --hard A. The current branch now ends at A, with otherbranch 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.)

影子的影子 2024-09-21 20:06:46

请注意,这是一个简化的解释,旨在作为理解这一复杂功能的第一步。

对于想要在每个命令之后可视化其项目状态的视觉学习者可能会有所帮助:

给定:- 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 (or git 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 commit

git reset --mixed A (or git reset A) and you will see B and C's stuff in the 'unstaged files' area ready to be moved to staged 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)

苍风燃霜 2024-09-21 20:06:46

所有其他答案都很棒,但我发现最好通过将文件分为三类来理解它们:unstagedstagedcommit

  • --hard 应该很容易理解,它恢复了所有
  • --mixed (默认)
    1. 未暂存文件:不更改
    2. 已暂存文件:移至未暂存
    3. 提交文件:移至未暂存
  • --soft
    1. 未暂存文件:不更改
    2. 暂存文件:不要更改
    3. 提交文件:移至暂存

总之:

  • --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) :
    1. unstaged files: don't change
    2. staged files: move to unstaged
    3. commit files: move to unstaged
  • --soft:
    1. unstaged files: don't change
    2. staged files: dont' change
    3. commit files: move to staged

In summary:

  • --soft option will move everything (except unstaged files) into staging area
  • --mixed option will move everything into unstaged area
小嗲 2024-09-21 20:06:46

在这些情况下,我喜欢一个能够解释这一点的视觉效果:

git reset --[hard/mixed/soft]

在此处输入图像描述

所以每一个都会影响不同的范围:

  1. Hard =>工作目录 + 索引 + HEAD
  2. 混合 =>索引+HEAD
  3. 软=>仅 HEAD(索引和工作目录不变)。

In these cases I like a visual that can hopefully explain this:

git reset --[hard/mixed/soft] :

enter image description here

So each one affects different scopes:

  1. Hard => WorkingDir + Index + HEAD
  2. Mixed => Index + HEAD
  3. Soft => HEAD only (index and working dir unchanged).
鹿港巷口少年归 2024-09-21 20:06:46

您不必强迫自己记住它们之间的差异。想想你实际上是如何做出承诺的。

  1. 进行一些更改。

  2. git add .

  3. git commit -m "我做了某事"

Soft、Mixed 和 Hard 是让你放弃从 3 到 1 所做的操作的方法。

  • Soft “假装”到从来没有看到你做过git commit
  • 混合“假装”从未看到您进行了 git add 。
  • “假装”从未看到您对文件进行了更改。

You don't have to force yourself to remember differences between them. Think of how you actually made a commit.

  1. Make some changes.

  2. git add .

  3. 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.

  • Soft "pretended" to never see you have did git commit.
  • Mixed "pretended" to never see you have did git add .
  • Hard "pretended" to never see you have made file changes.
不知在何时 2024-09-21 20:06:46

这里是对 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.

月下凄凉 2024-09-21 20:06:46

mkarasek 的答案很棒,简单来说我们可以说...

  • git reset --soft :将 HEAD 设置为预期的提交,但保留上次提交的更改
  • < code>git reset --mixed :与 git reset --soft 相同,但唯一的区别是它取消了上次提交的更改
  • git reset --hard code> :在您指定的提交上设置您的 HEAD ,并重置上次提交的所有更改,包括未提交的更改。

--soft--mixed 有点相似,唯一的区别是,如果您想将更改保留在暂存区域中,请使用 -- soft,如果您不想在暂存区域中进行更改,请使用 --mixed 代替。

mkarasek's Answer is great, in simple terms we can say...

  • git reset --soft : set the HEAD to the intended commit but keep your changes staged from last commits
  • git reset --mixed : it's same as git reset --soft but the only difference is it un stage your changes from last commits
  • git reset --hard : set your HEAD on the commit you specify and reset all your changes from last commits including un committed changes.

--soft and --mixed are a bit similar, the only difference is, if you want to keep your changes in staging area use --soft, and if you don't want your changes in staging area use --mixed instead.

櫻之舞 2024-09-21 20:06:46

在讨论这三个选项之前,必须了解三件事。

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.

心房的律动 2024-09-21 20:06:46

这里有很多答案对 git reset --soft 存在误解。虽然在特定条件下 git reset --soft 只会更改 HEAD(从分离的头状态开始),但通常(并且为了预期用途),< strong>它会移动您当前签出的分支引用。当然,如果您没有签出分支,它就无法执行此操作(因此特定条件 git reset --soft< /code> 只会更改 HEAD)。

我发现这是考虑 git reset 的最佳方式。您不只是移动 HEAD一切都这样做),您还移动了分支引用,例如master。这与运行 git commit 时发生的情况类似(当前分支与 HEAD 一起移动),只不过不是创建(并移动到)一个新的 /em> 提交,您将移至先前 提交。

这是重置的要点,将分支更改为新提交以外的内容,而不是更改HEAD您可以在文档示例中看到这一点:

撤消提交,使其成为主题分支

 $ git 分支主题/wip (1)
          $ git reset --hard HEAD~3 (2)
          $ git checkout 主题/wip (3)
  1. 您已经进行了一些提交,但意识到它们进入“master”分支还为时过早。您想在主题分支中继续完善它们,因此在当前 HEAD 上创建“topic/wip”分支。
  2. 回退主分支以删除这三个提交。
  3. 切换到“topic/wip”分支并继续工作。

这一系列命令有什么意义呢?您想要移动一个分支,这里是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 which git reset --soft will only change HEAD (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 where git reset --soft will only change HEAD).

I've found this to be the best way to think about git reset. You're not just moving HEAD (everything does that), you're also moving the branch ref, e.g., master. This is similar to what happens when you run git commit (the current branch moves along with HEAD), 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 changing HEAD. You can see this in the documentation example:

Undo a commit, making it a topic branch

          $ git branch topic/wip     (1)
          $ git reset --hard HEAD~3  (2)
          $ git checkout topic/wip   (3)
  1. You have made some commits, but realize they were premature to be in the "master" branch. You want to continue polishing them in a topic branch, so create "topic/wip" branch off of the current HEAD.
  2. Rewind the master branch to get rid of those three commits.
  3. Switch to "topic/wip" branch and keep working.

What's the point of this series of commands? You want to move a branch, here master, so while you have master checked out, you run git 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 the git 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. While git reset --soft HEAD does nothing (because it says move the checked out branch to the checked out branch), git reset --mixed HEAD, or equivalently git 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 to git checkout <ref>, except that (and this is the crucial point about reset) all forms of git reset move the branch ref HEAD 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 the HEAD. That's what the HEAD is, a pointer to wherever you are. HEADis you, and so will move whenever you do.

陪我终i 2024-09-21 20:06:46

--mixed vs --soft vs --hard:

--mixed:

   Delete changes from the local repository and staging area.

   It won't touch the working directory.

   Possible to revert back changes by using the following commands.

     - git add

     - git commit

   Working tree won't be clean.

--soft:

    Deleted changes only from the local repository.

    It won't touch the staging area and working directory.

    Possible to revert back changes by using the following command.

     - git commit.

    Working tree won't be clean

--hard:

    Deleted changes from everywhere.

    Not possible to revert changes.

    The working tree will be clean.

注意: 如果提交已确认到本地存储库并放弃这些提交,我们可以使用:

 `git reset command`.

但是如果提交已确认到远程存储库,则不建议使用重置命令,我们必须使用revert命令来放弃远程提交。

--mixed vs --soft vs --hard:

--mixed:

   Delete changes from the local repository and staging area.

   It won't touch the working directory.

   Possible to revert back changes by using the following commands.

     - git add

     - git commit

   Working tree won't be clean.

--soft:

    Deleted changes only from the local repository.

    It won't touch the staging area and working directory.

    Possible to revert back changes by using the following command.

     - git commit.

    Working tree won't be clean

--hard:

    Deleted changes from everywhere.

    Not possible to revert changes.

    The working tree will be clean.

NOTE: If the commits are confirmed to the local repository and to discard those commits we can use:

 `git reset command`.

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.

七色彩虹 2024-09-21 20:06:46

简短回答在什么情况下使用这 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 reset
少女情怀诗 2024-09-21 20:06:46

git reset 命令各个选项之间的基本区别如下。

  • --soft:仅将 HEAD 重置为您选择的提交。工作原理与 git checkout 基本相同,但不会创建分离的头状态。
  • --mixed(默认选项):将 HEAD 重置为您在历史记录中选择的提交并撤消索引中的更改。
  • --hard:将 HEAD 重置为您在历史记录中选择的提交,撤消索引中的更改,并撤消工作目录中的更改。

Basic difference between various options of git reset command are as below.

  • --soft: Only resets the HEAD to the commit you select. Works basically the same as git checkout but does not create a detached head state.
  • --mixed (default option): Resets the HEAD to the commit you select in both the history and undoes the changes in the index.
  • --hard: Resets the HEAD to the commit you select in both the history, undoes the changes in the index, and undoes the changes in your working directory.
心意如水 2024-09-21 20:06:46

--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.

怪我太投入 2024-09-21 20:06:46
  • 所有类型的重置都会更改存储库中的 HEAD。 此外...
  • git reset --soft 将从存储库中删除的提交中的更改移动到索引中,并合并到已经存在的任何内容中。
  • git reset --hard 会丢失工作树索引中的更改。
    它是唯一改变工作树的。

图表支持文字说明

  • All types of reset change the HEAD in the repo. Additionally...
  • 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.

diagram supporting text explanation

坠似风落 2024-09-21 20:06:46

莫阿里用最简单的术语来说,这是另一个简单的解释:

--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 + delete added changes

--hard: --mixed + recover working tree file changes (CAREFUL!)

腻橙味 2024-09-21 20:06:46

公共信息

这三个选项 --soft--mixed--hard 共享公共信息,例如:

  • 它们都移动 分支HEAD 同时,而不仅仅是特定 commit hashHEAD
  • commit hash 不存在时指定,HEAD 是默认值
  • 可以使用 reflogreset 来恢复命令以返回到原始commitHEAD 之前处于的代码>

--soft

  • 它不会修改 工作目录
  • 它不会对 Staging 中的文件执行任何操作>
  • HEADcommit hash 之间发生的修改被移至 Staging

--mixed

  • 它不会修改 工作目录
  • Staging 中的所有文件都将从 Staging 中删除并移至工作目录
    就像您执行了 git Restore --staged 一样,
  • HEADcommit hash 之间发生的修改不会移至 Staging
  • --mixedgit reset 的默认值

我们可以说 --mixed 等于 --soft > 但是:

  1. 不执行 git add
  2. 将所有文件从 Staging 删除到 工作目录

有趣的事实:执行--mixed后在git status中看到,当我们执行git add .后,我们会得到相同的git status code> 就好像我们执行了 --soft

--hard

--hard 是危险的,应该谨慎使用,因为:

  • 它会移动 HEAD提交哈希并强制对工作目录进行更改
  • 它会删除工作目录中的任何修改,而无法恢复它们< br>
    也就是说,它会丢弃修改的文件
  • 它还会删除Staging中的任何文件

注意:谨防使用--hard 因为它将影响 工作目录 并强制它匹配指定的提交
并且工作目录中的任何修改文件都将被丢弃

因此,在使用git reset --hard之前并且如果当前有文件正在修改在工作目录中,您应该在执行git reset --hard之前将这些修改移到其他地方。这就是 git stash 发挥作用的地方,它可以帮助您

总结软、混合和硬之间的差异

选择工作目录暂存文件未暂存的修改文件HEAD 和指定提交之间所做的更改
保持原样保持原样移动到 暂存区域移动到 暂存区域
混合保持原样移动到 工作目录它们保持在 中的原样工作目录它们保持在工作目录中的原样
强制替换以使工作目录与指定中的版本匹配commit摆脱它摆脱它摆脱它

Common Info

The three options --soft, --mixed and --hard share common info like:

  • They all move the branch and HEAD simultaneously, not just the HEAD to the specific commit hash
  • When commit hash is not specified, the HEAD is being the default
  • Reverting the command can be done using reflog and reset to return to the original commit that the HEAD was on before

--soft

  • It doesn't modify the Working Directory
  • It doesn't do anything with files in the Staging
  • The modifications that occurred between HEAD and commit hash are moved to the Staging

--mixed

  • It doesn't modify the Working Directory
  • All files in the Staging are removed from the Staging and moved to the Working Directory
    as if you performed git restore --staged
  • The modifications that occurred between HEAD and commit hash are not moved to the Staging
  • --mixed is the default value for git reset

We can say that --mixed equals --soft but:

  1. without executing git add
  2. Remove all files from the Staging to the Working Directory

Fun fact: What you see in git status after executing --mixed, after we perform git add ., we will get the same git status as if we executed --soft

--hard

--hard is dangerous and should be used with caution because:

  • It moves the HEAD to the commit hash and forced the changes on the Working Directory
  • It gets rid of any modifications in the Working Directory without a way to recover them
    meaning, it discards the Modified Files
  • It also rid of any files in the Staging

Note: Beware of using --hard as it will affect the Working Directory and force it matchs the specified commit
And any Modified Files in the Working Directory will be discarded

So, before using git reset --hard and if there are files currently being modified in the Working Directory, you should move these modifications elsewhere before executing git reset --hard. This is where git stash comes in and help you

Summarizing the differences between soft, mixed, and hard

SelectionWorking DirectoryStaged FilesUnstaged Modified FilesChanges made between HEAD and the specified commit
softremain as isremain as isMoved to the Staging AreaMoved to the Staging Area
mixedremain as isMoved to the Working DirectoryThey remain as they are in the Working DirectoryThey remain as they are in the Working Directory
hardForced to be replaced to make the Working Directory match the version it was in the specified commitGet rid of itGet rid of itGet rid of it
固执像三岁 2024-09-21 20:06:46

我不是 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)

  1. 第一个要点是创建一个新分支gitbranch mynewbranch。然后得到:

ABCD(master 和 mynewbranch)

  1. 让我们假设现在想要回到 A(之前有 3 次提交)。 第二个要点是使用命令 git reset --hard 即使人们可以在网上看到它是危险的。是的,这很危险,但仅限于未提交的更改。因此,做法是:

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)

  1. The first main point is to create a new branch: git branch mynewbranch. Then one get:

A-B-C-D (master and mynewbranch)

  1. Let’s suppose now that one want to come back to A (3 commits before). The second main point is to use the command git reset --hard even if one can read on the net that it is dangerous. Yes, it’s dangerous but only for uncommitted changes. Thus, the way to do is:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文