git-reset的--merge和--keep标志的典型用例是什么?

时间:2014-08-28 15:59:06

标签: git git-reset

recent answer中,他详细介绍了git-reset三个最常用选项(--hard--mixed--soft的典型用例),torek顺便提到git-reset还提供了两个相对深奥的标志,称为--merge--keepgit-reset man page描述了这两个标志如下:

--merge

   Resets the index and updates the files in the working tree
   that are different between <commit> and HEAD, but keeps
   those which are different between the index and working tree
   (i.e. which have changes which have not been added). If a
   file that is different between <commit> and the index has
   unstaged changes, reset is aborted.

   In other words, --merge does something like a git read-tree
   -u -m <commit>, but carries forward unmerged index entries.

--keep
    Resets index entries and updates files in the working tree
    that are different between <commit> and HEAD. If a file that
    is different between <commit> and HEAD has local changes,
    reset is aborted.

我完全理解何时使用--hard--mixed--soft,但我在阅读torek的答案时只知道--merge--keep存在,我想不出这两个标志的实际用例......在什么情况下你通常使用这两个标志?

我主要是寻找一个简单的英语解释。以下this answer by VonC段,其中列出了git reset --soft的典型用例,作为模型:

  

[...]每次:

     
      
  • 你对你最终得到的结果感到满意(在工作树和索引方面)
  •   
  • 你不满意所有让你去那里的承诺:
  •   
     

git reset --soft就是答案。

但是,我不会对这些旗帜进行一些小实验,这与我在this answer of mine中发布的愚蠢购物清单示例相似。

4 个答案:

答案 0 :(得分:5)

坦率地说,我对此并不十分肯定;我自己从未使用--merge--keep模式。但是,发行说明表明在git版本1.6.2中添加了git reset --merge,并附有以下注释:

  • git reset --merge是一种新方式,其工作方式与此类似 git checkout切换分支,同时进行本地更改 切换到另一个提交。

并在1.7.1中添加了--keep

  • git reset了解了--keep选项,可让您放弃提交 靠近小费,同时以类似的方式保留您的本地更改 git checkout branch的作用。

然后,在1.7.9:

  • git checkout -B <current branch> <elsewhere>更直观 拼写git reset --keep <elsewhere>的方式。

告诉我们--keep背后的想法是,你已经开始在某个分支上工作了,然后你意识到:哦,这个分支应该从其他一些分支(可能是其他分支的尖端) 。例如,您可以:

$ git checkout devel
$ git checkout -b fix-bug-1234

然后做一些工作来修复下一个版本的bug 1234;但后来有人说:&#34;嘿,我们需要修复旧版本版本的错误1234!&#34;现在,您希望fix-bug-1234release而不是devel分支出来。与此同时,你还没有投入任何东西。所以你:

$ git checkout -B fix-bug-1234 release

将其移至&#34;即将发布&#34;而不是&#34;脱离开发#34;哪个适用于1.7.9或更高版本,但在1.7.1到1.7.8中你需要拼写它git reset --keep

这可能解释--keep,但--merge仍然有点神秘。

答案 1 :(得分:1)

我同意,乍一看这些标志似乎是异国情调的。我花了几个小时来理解它们,但是区别很明显:--keep取消暂存索引,而--merge完全丢弃索引。

回到典型的用例:假设您有一个特定于本地环境的配置文件,例如,包含本地数据库的凭据。当您要进行“硬”重置时,请确保您不想丢失本地更改。在这种情况下

git reset --keep <commit>

完美地完成了这项工作。这表明您更想使用--keep标志而不是--hard标志。

标志--merge--keep更具攻击性,因为它会完全丢弃索引(请注意,在这种情况下,与--keep相反,您可能会丢失工作),但是在我认为两者的实际用例是相同的。

最初,我们引入了git reset --merge来中止合并,但是现在更喜欢使用git merge --abort(第一个选项在1.6.2版本中引入,而第二个选项在1.7.4中引入)

答案 2 :(得分:1)

来自https://git-scm.com/docs/git-reset

<块引用>

reset --keep 用于删除一些最后的 在当前分支中提交,同时保持工作中的更改 树。如果提交中的更改之间可能存在冲突,我们 想要删除以及我们想要保留的工作树中的更改, 不允许重置。这就是为什么如果两者都存在是不允许的 工作树和 HEAD 之间以及 HEAD 和 目标。为安全起见,当有未合并时也是不允许的 条目。

我可以考虑有一些本地提交的场景:Commit0、Commit1、Commit2、...、CommitX、CommitY、...、CommitN

并且我想放弃 Commit1..CommitX 中的更改,但保留 CommitY..CommitN 中的更改

为了做到这一点,我可以使用 git reset --soft CommitX,然后使用 git reset --keep Commit0

我想如果没有 --keep,有人需要使用 stash 才能做到这一点。

答案 3 :(得分:0)

试试这个。

如果你从树枝上拉下来,在那之后你会看到,哦!有多重冲突。然后突然你想起你从错误的分支中拉出然后它会帮助恢复它。

git reset --merge HEAD@{1}