Git 在没有任何提交历史的情况下合并功能分支

Git merge feature branch WITHOUT any commit history

假设我创建了一个新的功能分支并向该功能分支提交了大量内容。我的同事也做了一些提交,所以主分支。如何将我的更改合并到 master 分支但 master 分支显示一次提交?我试过合并,所有提交都显示出来,它表明我分支了。我已经尝试过变基,这并没有显示我分支出来但仍然显示了我所有的提交。在此先感谢您的帮助。

使用 git merge --squash(这会迫使您之后也使用 git commit)。

描述

在 Git 中,提交 历史。您不能在不添加历史记录的情况下添加提交,因为这些是同一回事。那么,您想要的是进行 单个 提交 而不是 合并提交 产生与好像相同的结果你已经进行了实际的合并提交.

有多种方法可以做到这一点,但最简单的方法是使用 git merge --squash。此命令执行我所说的 "verb part"、to merge——执行合并操作——但不是进行 merge commit , 这是典型 git merge 的形容词或名词部分,它进行普通的非合并提交。

更准确地说,它跳过 最终提交,迫使您使用git commit 自己完成。最后的提交,你必须让自己像这样,是一个普通的非合并提交。如果我们按照我喜欢的方式绘制提交,我们从这个开始:

...--o--o--o   <-- mainline
      \
       o--o--o   <-- yourbranch

如果您使用 git checkout mainline; git merge yourbranch 进行正常的日常合并,结果是:

...--o--o--o---M   <-- mainline
      \       /
       o--o--o   <-- yourbranch

这就是为什么您的三个提交现在被添加到主线分支:提交 M,新的合并,有 两个 个父项,其中一个是原来的主线,另一条是你自己的分支。 (您的三个提交现在在两个 分支上。)

但是,如果我们使用 git merge --squash,我们会得到这个:

...--o--o--o---S   <-- mainline
      \
       o--o--o   <-- yourbranch

与新提交 S 关联的 内容 与您通过提交 获得的内容完全相同 =19=],但新提交 S 只有一个父级,因此它不会将您的三个提交关联到主线分支。您现在可以在以后自由删除您的分支。当你这样做时,你的三个提交变得不可能找到,并且相对很快,Git 实际上将它们完全删除。1

请注意,您的分支 不会自行消失 。这里的名称 yourbranch 使您最初的三个提交保持活动状态。然而,如果你在你的分支上做更多的工作,那不是很有用:一旦你挤压合并(并提交),你通常应该考虑你的分支 "dead",并在你的挤压合并提交后删除它S 相当可靠。不过,您可能希望保留它一段时间,以防万一 S 被证明是错误的并且您或您的团队选择恢复 S:在这种情况下,您可以修复自己的分支,然后使用 yourbranch.

的更新版本重新执行 git merge --squash

1通常,Git 努力确保明显删除的提交至少保留一个月左右。但是,如果您删除分支名称本身,分支的 reflog(保持提交的内容之一)也会消失。您现在依赖 HEAD reflog。如果您在此存储库中签出提交,这也会将提交保留一个月左右,但如果没有,则不会。

How do I merge my change onto the master branch but master branch show one single commit?

这有点模棱两可。

正常的合并确实会添加一个新的提交,但是新的提交将 "other" 分支的所有提交合并到 "this" 分支的历史记录中 - 它们都变成了 "reachable"分支 - 因此 default 命令的输出 git log 显示了所有这些提交,正如您所观察到的那样。

如果唯一的要求是查看历史记录而不查看来自"other"分支的个人提交,最简单的解决方案是说

git log --first-parent

这使您可以在不实际丢弃任何信息的情况下浓缩历史视图。如果在未来的某个案例中您想要更详细地了解分支如何演变的历史(例如跟踪错误),它可能会很有用。它还确保如果您在 "other" 分支上做更多工作,您仍然可以合并这些额外的更改,而不会遇到很多不必要的麻烦。

特别是,如果 "other" 分支已与其他开发人员共享,则保留的信息可能特别重要 - 这是最常见的假设,如果您曾经 push 编辑 "other"分支.

但有时从历史的角度来看,单个提交是完全无用的,其目的是完全丢弃它们(以及包含它们的分支)。例如,也许您定期提交,无论您的代码处于什么状态,随时插入和删除调试代码,存储未构建和通过测试的状态等。使用这样的工作流是有原因的,并且在这种情况下,可能需要挤压合并(或挤压单个提交的交互式变基)来生成 "clean" 历史记录。

您可以尝试 "have your cake and eat it to",但使用 --squash 合并来创建简化的历史记录,同时仍然保留原始分支以获得细粒度的历史记录。但是 git 在这种情况下会忘记历史之间的关系,这很容易导致远远超过其价值的麻烦。

最终取决于您(和您的团队,如果适用)选择的工作流程。请注意您在做什么以及 为什么 ,因为从表面上看,您可能正在寻求解决便士钉问题的大锤解决方案,如果是这样,您应该知道的附带损害。