在recent answer中,他详细介绍了git-reset
三个最常用选项(--hard
,--mixed
和--soft
的典型用例),torek顺便提到git-reset
还提供了两个相对深奥的标志,称为--merge
和--keep
。 git-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中发布的愚蠢购物清单示例相似。
答案 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-1234
从release
而不是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}