我经常发现自己想从本地存储库中压缩两次或更多次提交。我这样做的策略是从软重置开始,然后提交所有重置的更改。
对于软重置,我使用以下命令:
git reset --soft HEAD~n
其中n是我想重置的提交数。如果我没有将合并提交包含在我想重置的提交数量中,例如,如果我在当前分支上提交了四次并想对HEAD〜4进行软重置,则此方法可以正常工作。
但是,假设我的4次提交后,我将另一个分支合并到当前分支中。 Git隐式提交合并更改,并且在我执行git log时显示。现在,如果我想将软复位回HEAD〜5(4个提交+合并提交),除了我打算重设的4个提交之外,git将忽略合并提交并重置下一个最新的非合并提交。 。本质上,我应该重设HEAD〜4-git在重设时似乎忽略合并提交。
为什么Git会有这种行为?以及如何在软重置中包括这些合并提交?
(让我们举个例子:我按时间顺序提交了ABCDEF,F是合并提交。 git reset --soft HEAD〜4 会将分支重置为A:重置BCDE,提交F未包含在4.)中。
答案 0 :(得分:1)
好吧,这不是因为git忽略了合并提交。这是因为~
和^
在Git中的工作方式。
~n
表示通过第一个父级在层次结构中上移n levels
。如果您将其指定为^n
,则意味着转到n th
父级,从从左侧开始。
如果我们在您的git储存库中运行git log --graph --pretty=oneline
(您提供的示例),则可能会出现以下内容:
* da497fa213169e75b9cec382e28561d5e56f6daf (HEAD -> master) f (merge)
|\
| * aaa519bce409d0fb5e187dff6ed82d73d7cd437b (Dev) e
|/
* f537237e48fc7218af288ddc91a02c1e24ea1887 d
* 2c41ee71ee7b9b450cd10eab685e0007fe92b688 c
* 411c96c85a2e34bf798cab5c0e6f4532a5ebfe35 b
* c9d38077a5704df382b0fd0d83d4fcdf7c408f23 a
请注意,提交f
有两个父级(由于合并提交)。现在,当您说HEAD〜4时,它将在HEAD之后从其左侧开始的b
中查找4个提交。 (它不需要e
,因为它位于second parent
的{{1}}中。)
您可以使用f
命令来解析并获取特定的提交ID。
例如:如果运行git rev-parse
,将看到它返回git rev-parse HEAD~4
的提交ID。
我认为,您不必为此担心,因为git最终会将您的分支重置为给定的提交ID。但是,假设您想重置分支以提交a
,现在您需要告诉它正确的访问方式。
所以您可以告诉它,选择HEAD的第二个父级,然后重置为该父级。
那将等于:HEAD ^ 2
如果您将reset命令指定为:
,您还可以将其扩展到e
到a
。
e
。
但是我认为,在您的情况下这不是必需的。
以下是从git git reset --soft HEAD^2~3
文档中摘录的内容。
rev-parse
https://git-scm.com/docs/git-rev-parse/1.8.0#_specifying_revisions
希望它会有所帮助:)