我希望拆分提交,但不确定要使用哪个重置选项。
我正在查看页面Can you explain what "git reset" does in plain english?,但我意识到我并不真正理解git索引或临时区域是什么,因此解释没有帮助。
--mixed
和--soft
的用例在该答案中看起来与我相同(当你想修复并重新发送时。)有人可以将其分解得更多吗?我意识到--mixed
可能是可以选择的,但我想知道为什么。最后,--hard
怎么办?
有人能给我一个工作流程示例,说明如何选择3个选项吗?
答案 0 :(得分:1262)
修改存储库中的文件时,更改最初是未分阶段的。为了提交它,您必须将其暂存 - 也就是说,使用git add
将其添加到索引中。进行提交时,提交的更改是已添加到索引的更改。
git reset
至少会更改当前分支(HEAD
)指向的位置。 --mixed
和--soft
之间的区别在于您的索引是否也被修改。所以,如果我们在分支master
上进行了这一系列的提交:
- A - B - C (master)
HEAD
指向C
,索引与C
匹配。
当我们运行git reset --soft B
时,master
(以及HEAD
)现在指向B
,但索引仍然来自C
; git status
会将其显示为已上演。因此,如果我们此时运行git commit
,我们将获得与C
相同更改的新提交。
好的,从这里再次开始:
- A - B - C (master)
现在让我们做git reset --mixed B
。 (注意:--mixed
是默认选项)。同样,master
和HEAD
指向B,但这次索引也会被修改为匹配B
。如果我们此时运行git commit
,则由于索引与HEAD
匹配,所以不会发生任何事情。我们仍然在工作目录中进行了更改,但由于它们不在索引中,git status
将它们显示为未分阶段。要提交它们,您可以git add
然后像往常一样提交。
最后,--hard
与--mixed
相同(它会更改您的HEAD
和索引),但--hard
也会修改您的工作目录。如果我们在C
并且运行git reset --hard B
,那么C
中添加的更改以及您拥有的任何未提交的更改都将被删除,并且工作副本中的文件将会被删除匹配提交B
。由于您可以通过这种方式永久丢失更改,因此在执行硬重置之前应始终运行git status
以确保您的工作目录是干净的,或者您可以丢失未提交的更改。
最后,一个可视化:
答案 1 :(得分:67)
请注意,这是一个简化的解释,旨在帮助您了解这一复杂功能。
对于想要在每个命令之后可视化项目状态的视觉学习者可能会有所帮助:
对于使用打开颜色的终端的用户 (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的变化(就好像它们从未存在过一样)
对于那些使用像“塔”这样的GUI程序的人来说。或者' SourceTree'
git reset --soft A
您将在'分阶段文件中看到B和C的内容。区域准备提交
git reset --mixed A
(或git reset A
),您将在未上映的文件中看到B和C的内容'区域准备移动到上演然后提交
git reset --hard A
您将不再在任何地方看到B和C的变化(就好像它们从未存在过一样)
答案 2 :(得分:63)
用最简单的术语来说:
--soft
:取消提交更改,更改将暂停( index )。--mixed
(默认):取消提交+非舞台更改,更改将保留在工作树中 --hard
:取消提交+非舞台+删除更改,一无所有。答案 3 :(得分:25)
许多现有答案似乎都无法回答实际问题。它们是关于命令的功能,而不是您(用户)想要的—用例(em)。但这就是OP的要求!
根据您发出git reset
命令时的确切表达,表达您的歉意可能会更有帮助。假设我们有这个:
A - B - C - D <- HEAD
以下是一些可能的遗憾以及如何解决这些问题:
git reset --soft A
。我现在可以立即提交并保存所有自A 提交以来的所有更改。
git reset --mixed A
。提交已消失,索引又回到了A,但是工作区看起来仍然像D之后一样。所以现在我可以在一个完全不同的分组中进行添加和提交了。
创建一个新分支otherbranch
,然后创建git reset --hard A
。现在,当前分支以A otherbranch
结尾于A。
(当然,您也可以使用硬重置,因为您希望B,C和D从未发生过。)
答案 4 :(得分:21)
以下是TortoiseGit用户的基本说明:
git reset --soft
和--mixed
保持您的文件不变。
git reset --hard
实际更改您的文件以匹配您重置的提交。
在TortoiseGit中,索引的概念被GUI非常隐藏。修改文件时,不必运行git add
将更改添加到暂存区/索引。当简单地处理对未更改文件名的现有文件的修改时,git reset --soft
和--mixed
是相同的!如果添加新文件或重命名文件,您只会注意到不同之处。在这种情况下,如果运行git reset --mixed,则必须从 Not Versioned Files 列表中重新添加文件。
答案 5 :(得分:10)
在这些情况下,我喜欢可以希望对此进行解释的视觉效果
git reset --[hard/mixed/soft]
:
所以每种效果都有不同的范围
答案 6 :(得分:4)
在进入这三个选项之前,必须先了解三件事。
1)历史/ HEAD
2)阶段/指数
3)工作目录
reset --soft:历史记录已更改,HEAD已更改,工作目录未更改。
reset --mixed:历史记录已更改,HEAD已更改,工作目录已更改为未分期数据。
reset --hard:历史记录已更改,HEAD已更改,工作目录已更改,数据丢失。
与Git --soft一起使用总是安全的。应该在复杂的要求中使用其他选项。
答案 7 :(得分:2)
您不必强迫自己记住它们之间的差异。考虑一下您实际上是如何提交的。
1。进行一些更改。
2.git add。
3.gc -m“我做了什么”
软,混合和硬是使您放弃从3到1进行的操作的方式。
软件“伪装”为永远不会看到您做了“ gc -m”。
混合“假装”,以至于您从未看到过“ git add”。
很难“假装”从未看到您进行过文件更改。
答案 8 :(得分:1)
使用3个选项的简短回答:
要保留代码中的当前更改,但要重写提交历史记录:
soft
:您可以一次提交所有内容并使用新描述创建新提交(如果您使用torotise git或任何其他大多数GUI,这是一个使用的,因为您仍然可以勾选哪些文件你想要在提交中以及使用不同文件进行多次提交。在Sourcetree中,所有文件都将被提交以进行提交。)mixed
:在进行提交之前,您必须再次将单个文件添加到索引中(在Sourcetree中,所有已更改的文件都将被取消暂存)要在代码中实际丢失更改:
hard
:您不必重写历史记录,但也会在重置之前丢失所有更改答案 9 :(得分:1)
git reset命令的各种选项的基本区别如下。
答案 10 :(得分:1)
--soft
:告诉Git将HEAD重置为另一个提交,因此不会以任何方式更改索引和工作目录。原始HEAD和提交之间的所有文件都将被暂存。
--mixed
:就像软件一样,这会将HEAD重置为另一个提交。它还将重置索引以匹配它,而不会触及工作目录。所有更改都将保留在工作目录中,并显示为已修改,但不会暂存。
--hard
:这会重置所有内容 - 它会将HEAD重置为另一个提交,重置索引以匹配它,并重置工作目录以匹配它。
--mixed
和--soft
之间的主要区别在于您的索引是否也被修改。详细了解here。
答案 11 :(得分:1)
这里有许多答案,对git reset --soft
有误解。在特定情况下,git reset --soft
仅会更改HEAD
(从分离的头部状态开始),通常(并用于预期用途),它会移动您当前拥有的分支引用。如果您没有签出分支,则当然无法执行此操作(因此,git reset --soft
仅会更改HEAD
的特定条件)。
我发现这是思考git reset
的最佳方法。您不仅在移动HEAD
(everything does that),还在移动分支引用,例如master
。这类似于您运行git commit
(当前分支随HEAD
移动)时发生的情况,除了移动(而不是创建(移动到) new )提交之外,到先前提交。
这是reset
的要点,将分支更改为新提交,而不更改HEAD
。在文档示例中是这样的:
撤消提交,使其成为主题分支
$ git branch topic/wip (1) $ git reset --hard HEAD~3 (2) $ git checkout topic/wip (3)
- 您已经进行了一些提交,但是意识到它们还不成熟,不能进入“ master”分支。您想继续在主题分支中对其进行润饰,因此在当前HEAD的旁边创建“ topic / wip”分支。
- 倒回master分支以摆脱这三个提交。
- 切换到“ topic / wip”分支并继续工作。
这一系列命令的意义是什么?您想将分支移动到这里master
,因此,在您master
签出后,可以运行git reset
。
这里票数最高的答案通常是好的,但是我想我应该添加它以纠正一些带有误解的答案。
git reset --soft <ref>
:将当前检出的分支的分支指针重置为指定参考处的提交。您的工作目录和索引中的文件不会更改。从此阶段开始执行操作将使您直接回到使用git reset
命令之前的状态。
git reset --mixed <ref>
或等效地
git reset <ref>
:
执行--soft
的操作 AND ,还会将索引重置为与指定引用处的提交匹配的索引。尽管git reset --soft HEAD
不执行任何操作(因为它说将已检出的分支移至已检出的分支),但是git reset --mixed HEAD
或等效的git reset HEAD
是常见且有用的命令,因为它将索引重置为您最后一次提交的状态。
git reset --hard <ref>
:执行--mixed
的操作 AND ,并且还会覆盖您的工作目录。该命令类似于git checkout <ref>
,除了(这是关于reset
的关键点)所有形式的git reset
都会移动分支ref HEAD
指向
说命令移动HEAD
是没有用的。任何更改提交历史记录中位置的命令都会移动HEAD
。这就是HEAD
是的内容,它是指向您身在何处的指针。 HEAD
is you,因此您每次操作都会移动。
答案 12 :(得分:1)
所有其他答案都很不错,但我发现最好将文件分为三类来理解它们:unstaged
,staged
,commit
:
--hard
应该很容易理解,它可以还原一切--mixed
(默认):
unstaged
文件:请勿更改 staged
文件:移至unstaged
commit
文件:移至unstaged
--soft
:
unstaged
文件:请勿更改 staged
文件:不要更改 commit
文件:移至staged
总结:
--soft
选项会将所有内容(unstaged
文件除外)移至staging area
--mixed
选项会将所有内容移至unstaged area
答案 13 :(得分:0)
mkarasek的答案很好,简单来说,我们可以说...
git reset --soft
:将HEAD
设置为预期的提交,但将更改从上一次提交暂存git reset --mixed
:与git reset --soft
相同,但唯一的不同是它取消了上一次提交所做的更改git reset --hard
:在您指定的提交上设置HEAD
并重置上一次提交中的所有更改,包括未提交的更改。 答案 14 :(得分:0)
我不是git专家,只是来到了这个论坛上了解它!因此,也许我的解释并不完美,对此感到抱歉。我发现所有其他答案都很有帮助,我将尝试提出另一个观点。我会稍作修改,因为我想这可能是作者的意图:“ 我是git的新手。在使用git之前,我正在重命名我的文件:main.c,main_1.c,main_2.c,当我执行专业更改时可以在遇到麻烦时返回。因此,如果我决定返回main_1.c,那很容易,并且我还保留了main_2.c和main_3.c,因为以后也可能需要它们。我如何使用git轻松地做同样的事情?” 对于我的答案,我主要使用上面Matt的最佳答案中的“后悔数字3”,因为我还认为最初的问题是“如果在使用git时感到后悔,我该怎么办?”。一开始情况是这样的:
A-B-C-D(管理员)
A-B-C-D(主服务器和mynewbranch)
Git重置-设置commitA的数量
或
Git重置--hard master〜3
然后获得: A(主)– B – C – D(mynewbranch)
然后,可以继续工作并从A(主)提交,但仍然可以通过检出另一个分支 git checkout mynewbranch 来轻松访问其他版本。 现在,让我们想象一个忘记了在命令 git reset --hard 之前创建新分支的过程。提交B,C,D丢失了吗?不,但是没有存储在任何分支中。要再次找到它们,可以使用以下命令: git reflog (被视为“安全命令”)(“万一遇到麻烦,请保持冷静并使用git reflog”)。该命令将列出所有提交,甚至包括那些不属于任何分支的提交。因此,这是查找提交B,C或D的便捷方法。
答案 15 :(得分:0)
-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`.
但是,如果提交已确认到远程存储库,则不建议使用reset命令,我们必须使用revert command
放弃远程提交。