如何在git中创建一个适当的合并提交,它也被压缩了
我正试图解决我的git历史记录中的一个问题 我有两个分支,我们称它们为如何在git中创建一个适当的合并提交,它也被压缩了,git,github,merge,Git,Github,Merge,我正试图解决我的git历史记录中的一个问题 我有两个分支,我们称它们为a和b,a是我的存储库的源分支,而b是从它分支出来的。许多合并的拉请求(合并提交和压缩提交的混合)发生在a,并且b没有重新设置基址,也没有针对b重新打开这些PRs。为了更新b,我(天真地)从a中挑选适用于b的合并提交 随着时间的推移,随着代码在a中的测试和批准,b现在等于a,差异为空,但历史显示,(正如预期的那样)提交存在差异。(b在Github中被视为在a之前提交的数量) 我想消除这种分歧,如果我执行从一个分支到另一个分支的
a
和b
,a
是我的存储库的源分支,而b
是从它分支出来的。许多合并的拉请求(合并提交和压缩提交的混合)发生在a
,并且b
没有重新设置基址,也没有针对b
重新打开这些PRs。为了更新b
,我(天真地)从a
中挑选适用于b
的合并提交
随着时间的推移,随着代码在a
中的测试和批准,b
现在等于a
,差异为空,但历史显示,(正如预期的那样)提交存在差异。(b
在Github中被视为在a
之前提交的数量)
我想消除这种分歧,如果我执行从一个分支到另一个分支的合并提交,我会得到一个长字符串的提交,没有任何更改(除了在Github上的某些情况下,它会变得混乱),这将污染任何一个分支的历史记录(如果允许的话)
e、 g.git merge a
fromb
或git merge b
froma
在日志中显示一长串提交。(编辑:这是带有--无ff
)
如果我执行挤压,我会收到一条很好的消息,列出那些没有更改的提交
e、 g.git merge a--squash
fromb
或git merge b--squash
froma
需要git commit--allow empty
但这并不能阻止“该部门领先/落后”的局面
因此,我的问题是如何生成单个提交(可以在任意一个分支中,也可以在两个分支中),以防止出现“前/后”情况
编辑:这主要是为了便于跟踪Github上发生的事情,我知道git是如何工作的,并且知道如何通过强制推动破坏一个或其他分支的历史来做到这一点,但我正试图以一种易于反思的方式保存这两个分支。这里唯一的真正答案是,你没有 Git存储的是一个提交图。每个提交都有自己唯一的散列ID,此存储库或任何其他存储库中的任何其他提交都不会使用。1每个提交还指向(向后)其父提交;这就是形成图表的原因 也就是说,给定一个线性提交链,使用大写字母代表它们的实际大而丑陋的哈希ID,我们可以这样绘制它们:
... <-F <-G <-H ...
I--J <-- branch1
/
...--G--H
\
K--L <-- branch2
我们需要两个分支名称来查找所有提交,因为Git的工作原理是让一个分支名称指向最后一个提交,我们称之为“分支的一部分”。提交J
是branch1
上的最后一次提交J
指向I
,后者指向H
。同时,名称branch2
指向commitL
,它指向K
,它指向H
。请注意,commitH
位于两个分支上(commitG
和更早版本也是如此)
如果H
有一个指向它的名称:
I--J <-- branch1
/
...--G--H <-- master
\
K--L <-- branch2
从M
出来的多个向后箭头同时指向J
和L
,这意味着branch1现在比branch2
早三次提交:从branch1
我们可以到达提交M
、J
和I
,以及L
和K
当然还有H
和更早的版本。从branch2
,我们可以到达L
和K
和H
及更早,但我们不能从H
前进到I
使用git merge--squash
,git将使用与mergeM
相同的内容进行新的提交,但不是两个向后箭头,而是只得到一个:
I--J
/ \
...--G--H M <-- branch1 (HEAD)
\
K--L <-- branch2
如果没有可以用来查找commitL
的名称,您将永远不会再看到它。因为commitL
是您用来查找commitK
的方法,所以您也不会再看到这个方法了。它们会在Git存储库中保留一段时间,确切的时间很难预测,因为这取决于仍然找到commitL
的任何隐藏(仅限reflog)名称,以及维护Git gc
命令清理未使用的提交并真正删除它们的时间。但是删除名称branch2
会删除branch2 reflog,因此唯一可能仍然记得L
原始哈希ID的reflog是头的reflog
(如果您有其他的分支和/或标记名可以记住提交L
和/或K
,它们仍然可以通过这种方式找到,并且不会被git gc
垃圾收集器收集。)
通常,在git merge--squash
之后,正确的做法是删除另一个分支名称,并完全忘记那些提交曾经存在过
1从技术上讲,任何从未“相遇”的Git存储库都可以无害地重用彼此的ID。在实践中,他们无论如何都不会。一个Git对象拥有与某个Git对象相同的散列ID的几率,就其自身而言,为2160分之一。正因为如此,随着对象数量的增加,这种可能性会迅速增加,但当对象数量少于数万亿时,这种可能性仍然是10-17分之一。另见
随着时间的推移,a
中的代码经过测试和批准,b
现在等于a,差异为空,但历史表明,(正如预期的那样)提交存在差异。我想消除这种分歧,如果我执行从一个到另一个的合并提交,我会得到一个很长的提交字符串[…],这会污染历史
您在历史记录中有不同的提交,或者有相同的提交。你不能两全其美
I--J
/ \
...--G--H M <-- branch1 (HEAD)
\
K--L <-- branch2
...--G--H--I--J--M <-- branch1 (HEAD)
\
K--L [abandoned]