我想拆分一个提交,但不确定使用哪个重置选项。

我正在看这页用简单的英语说,“git重置”是做什么的?,但我意识到我并不真正理解git索引或暂存区是什么,因此解释没有帮助。

此外,在我看来,在这个答案中——混合和——软的用例是相同的(当您想修复和重新承诺时)。有人能再详细解释一下吗?我知道,混合可能是最好的选择,但我想知道原因。最后,硬呢?

谁能给我一个工作流程的例子,如何选择3个选项会发生?


当前回答

简单回答这3个选项在什么情况下使用:

在代码中保留当前的更改,但要重写提交历史:

soft:你可以一次性提交所有内容,并使用新的描述创建一个新的提交(如果你使用tootise git或任何其他大多数gui,这是一个可以使用的,因为你仍然可以在提交中选择你想要的文件,并以这种方式对不同的文件进行多次提交。在Sourcetree中,所有文件都将被提交。) mixed:在提交之前,您必须将单独的文件再次添加到索引中(在Sourcetree中,所有更改的文件都将被取消staging)

要真正丢失您在代码中的更改:

难的是:你不仅重写了历史,而且还失去了你重置之前的所有更改

其他回答

所有其他的答案都很棒,但我发现最好通过将文件分解为三类来理解它们:非阶段性、阶段性和提交:

——困难应该是容易理解的,它恢复了一切 ——mixed(默认): 非暂存文件:不要更改 暂存文件:移至非暂存文件 提交文件:移动到非暂存状态 ——软: 非暂存文件:不要更改 阶段性文件:不要更改 提交文件:移动到阶段性

总而言之:

-软选项将移动所有(除了非暂存文件)到暂存区 混合选项会把所有东西都移到非舞台区域

-混合vs -软vs -硬:

--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命令来丢弃远程提交。

当您在存储库中修改一个文件时,更改最初是暂不执行的。为了提交它,你必须使用git add来执行它——也就是说,将它添加到索引中。当你提交时,提交的更改是那些已经添加到索引中的更改。

git重置更改,至少,当前分支(HEAD)指向的位置。-混合和-软之间的区别在于索引是否也被修改。如果我们在master分支上进行这一系列的提交:

- A - B - C (master)

头指向C,索引匹配C。

当我们运行git reset -soft B, master(因此HEAD)现在指向B,但索引仍然有从C的变化;Git状态将显示它们为阶段性。如果我们在这里运行git commit,我们会得到一个新的commit,和C一样。


好的,再从这里开始:

- A - B - C (master)

现在让我们进行git重置-mixed b(注意:-mixed是默认选项)。同样,master和HEAD指向B,但这一次索引也被修改以匹配B。如果我们在这一点上运行git commit,什么也不会发生,因为索引匹配HEAD。我们在工作目录中仍然有更改,但由于它们不在索引中,git状态将它们显示为未暂存。要提交它们,你需要git添加,然后像往常一样提交。


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


最后,一个可视化图:

以下是对TortoiseGit用户的基本解释:

Git复位-软-混合不动你的文件。

Git重置-实际上很难改变你的文件来匹配你重置的提交。

在TortoiseGit中,索引的概念被GUI隐藏得很好。当你修改一个文件时,你不必运行git add来将更改添加到暂存区域/索引中。当简单地处理现有文件的修改而不改变文件名时,git reset -soft和-mixed是一样的!只有添加新文件或重命名文件时才会注意到不同之处。在这种情况下,如果你运行git reset——mixed,你将不得不从Not Versioned Files列表中重新添加你的文件。

这里有许多关于git重置的误解的答案——软。虽然在特定的条件下git会重置——soft只会改变HEAD(从分离的HEAD状态开始),通常(对于预期的用途),它会移动您当前签出的分支引用。当然,如果你没有签出分支,它就不能这样做(因此git重置的特定条件-soft只会改变HEAD)。

我发现这是考虑git重置的最佳方式。你不只是移动HEAD(所有事情都是这样),你也移动了分支引用,例如master。这类似于运行git commit(当前分支与HEAD一起移动)所发生的情况,只是您没有创建(并移动到)一个新的提交,而是移动到先前的提交。

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

撤销提交,使其成为主题分支 $ git分支主题/wip (1) $ git重置-硬头~3 (2) $ git结帐主题/wip (3) 您已经提交了一些文件,但是意识到它们还不适合放在“主”分支中。你想在topic分支中继续打磨它们,所以在当前HEAD的基础上创建“topic/wip”分支。 倒回主分支以摆脱这三个提交。 切换到“topic/wip”分支并继续工作。

这一系列命令的意义是什么?你想移动一个分支,master,当你签出master时,你运行git reset。

这里投票最多的答案一般都很好,但我想我应该加上这个来纠正几个有误解的答案。

改变你的分支

Git reset——soft <ref>:重置当前检出分支的分支指针到指定引用处的提交,<ref>。工作目录和索引中的文件不会被更改。从这个阶段提交将把你带回到git reset命令之前的状态。

改变你的索引

Git重置——mixed <ref>

或者同样的

Git重置<ref>:

做什么——soft做AND还重置索引以匹配指定引用的提交。虽然git reset——soft HEAD什么都不做(因为它说将检出的分支移动到检出的分支),但git reset——mixed HEAD,或等价于git reset HEAD,是一个常见且有用的命令,因为它将索引重置为上次提交的状态。

也要更改工作目录

git reset——hard <ref>: does what——mixed does AND也覆盖你的工作目录。这个命令类似于git checkout <ref>,除了(这是关于重置的关键点)所有形式的git重置移动ref HEAD指向的分支。

关于“某某命令移动HEAD”的注释:

说命令移动HEAD是没有用的。任何改变您在提交历史中的位置的命令都会移动HEAD。这就是HEAD,一个指向你所在位置的指针。head就是你,所以无论你做什么,它都会移动。