43

在我的实验中,我无法找到两者之间的任何功能差异

git reset --hard

git reset --merge

使用说明也没有给出任何提示

--hard                reset HEAD, index and working tree
--merge               reset HEAD, index and working tree

我经常使用这个--hard选项,所以了解它是如何工作的。--merge选项和选项有什么区别--hard

干杯,奥利

也许一个例子在这里会有所帮助,让我们使用以下序列:

cd git_repo
touch file_one
git add file_one
git commit -m "commit one" # sha1 of 123abc
echo "one" >> ./file_one
git commit -a -m "commit two" # sha1 of 234bcd
echo "two" >> ./file_one
git add . # populate index with a change
echo "three" >> ./file_one # populate working area with a change

现在如果我尝试

git reset --merge 123abc

我明白了

error: Entry 'file_one' not uptodate. Cannot merge.
fatal: Could not reset index file to revision '123abc'

原因是 file_one 在工作区和索引中都有变化

为了解决这个问题,我做

git add .
git reset --merge 123abc

这次它有效,但是,我得到与git reset --hard. 索引为空,工作区为空,file_one 为空,就像第一次提交后一样。

有人可以提出说明差异的步骤吗?

4

5 回答 5

30

git reset 手册页

--hard 将工作树和索引与正在运行的树的索引匹配
               切换到。对工作树中跟踪文件的任何更改
               <commit> 丢失。

- 合并
              重置索引以匹配命名提交记录的树,并且
              更新命名提交和之间不同的文件
              工作树中的当前提交。

git reset --merge意味着是一个更安全的版本git reset --hard,当您的更改和其他人的更改混合在一起时,试图携带我们的更改。

于 2009-10-27T23:08:08.533 回答
14

文章“ Git undo, reset or revert? ”总结了不同的用法,当与 一起使用时ORIG_HEAD

# Reset the latest successful pull or merge
$ git reset --hard ORIG_HEAD

# Reset the latest pull or merge, into a dirty working tree
$ git reset --merge ORIG_HEAD

正如manojlds回答所提到的,以及博文中的说明,后者在您看到如下错误消息时特别有用:

fatal: You have not concluded your merge. (`MERGE_HEAD` exists)

线程“ [PATCH] 拒绝在合并期间合并”也详细说明了这一点:

git reset --merge HEAD

它填补了完全不同的情况,您在工作树中对一些未提交的更改进行了干净合并,但随后又想再次丢弃合并而不会丢失未提交的更改。
在没有更改的情况下,您只需使用--hard,但在这里您希望在合并它们的同时移动分支尖端,类似于git checkout -m移动 '' 所做的那样HEAD

于 2012-09-25T12:21:39.473 回答
9

当您对工作树中的更改进行拉取时,这很有帮助,并且发现合并不是预期的(您可能一直期望提交不会影响您正在处理的文件)。在这一点上,如果你这样做git reset --hard ORIG_HEAD,你会吹走一切,包括你的本地变化。如果这样做git reset --merge ORIG_HEAD,您将保留本地更改。

于 2012-08-13T03:11:38.660 回答
4

显然根据:

http://www.kernel.org/pub/software/scm/git/docs/git-reset.html

--hard - 将工作树和索引与要切换到的树的索引匹配。此后对工作树中跟踪文件的任何更改<commit>都将丢失。

--merge - 重置索引以匹配命名提交记录的树,并更新工作树中命名提交和当前提交之间不同的文件。

于 2009-10-27T23:02:51.050 回答
0

tl;dr git reset --merge用于git reset --keep撤消合并。git reset --keepgit reset --hard试图保留未分级的更改。此外,git reset --hard可能会更改未暂存的文件(git-reset):

以写入任何跟踪文件的方式的任何未跟踪文件或目录都将被简单地删除。

我认为@manojldsgit reset --merge涵盖了您通常想知道的内容(合并前工作树中的更改;冲突或干净合并)。因为这看起来像.git reset --merge

但您可能还需要考虑以下两种情况:

  1. 如果您在合并之前对工作树没有任何更改,并且您正在解决冲突,git reset --merge ORIG_HEAD那么与git reset --hard ORIG_HEAD. 除非您此时开始开发新功能(进行与解决冲突无关的更改)。也就是说,如果您想要撤消合并,您很可能想要撤消所有操作。在这种情况下,您可以简单地执行git merge --abort.

    git reset --merge ORIG_HEAD在这种情况下将保留未分级的更改。除了对有冲突的文件所做的更改(丢弃)和对暂存文件所做的更改(中止)。

    尽管理论上它可能很方便,但听起来不像git reset --merge.

  2. 如果您不在解决冲突的过程中,并且想要进行git reset --merge任意提交,它将尝试保留未暂存的更改。但也会如此git reset --keep。后者在合并过程中根本不起作用,并且忽略了分阶段的更改。

    如果它们不能保留未暂存的更改,它们将中止。如果您更改了在 和 之间也更改过的文件,则会发生这种HEAD情况<commit>

于 2022-02-22T15:56:02.897 回答