如何在不使用交互式 git 变基的情况下将两个 git 提交合并为一个提交?

How do i combine two git commits into a single commit without using an interactive git rebasing?

我正在开发一个被其他团队使用的功能分支,他们有很多开发人员,所以他们有很多提交。 我上次提交是在大约 10 天前,我打算今天再次提交,但我想确保从我这边开始提交一次。

我知道我可以使用 "git rebase -i HEAD~n" 实现此目的,但我不知道用什么数字代替 n,因为在这 10 天里,其他团队的 end.This 命令有超过 20 次提交如果您有连续提交,这是一个不错的选择,但它不适合我的场景。

虽然我已经完成了 git 提交的哈希码,但是除了 git 交互式变基之外还有什么方法可以让我只使用我的 git哈希码为 "pick",另一个为 "squash"。 这将使我免去经历 20 多次 git 提交的麻烦。

可以在不使用 git rebase -i 的情况下达到您想要的结果。学习该方法是值得的,这样您就可以真正 理解 git rebase 的作用,无论您是否使用 -i 选项。

实现您想要的结果可能是不明智的,尽管只有您和您的同事才能真正确定这一点。

您可以手动执行此操作的一种方法是 git checkout 通过哈希 ID 进行特定提交,并创建一个指向此提交的新分支名称。您在此处选择的提交应该是就在两个有问题的提交之前的提交。

然后你会 git cherry-pick -n 你想压缩成一个新提交的两个提交,并使用 git commit 提交结果。

现在您面临额外使用 git cherry-pick 将每个 后续 提交复制到新分支的问题。这并没有那么困难——事实上,只要有正确的散列 ID,一切都应该自动进行。您只需要找到正确的哈希 ID。

完成后,您需要说服您的同事放弃现有的功能分支并使用您重建的新功能分支。这个新分支有原始提交的副本,但它们是新的和改进的,因为它们建立在你对原始两个提交的压缩替换之上。

如果这听起来有点令人费解,好吧,这与您的 git rebase -i 所做的相同 — 除了当您使用 git rebase -i 时,您必须说服您的同事放弃名为 feature/foo 的分支以支持名称为 still feature/foo 的新分支,这有点令人困惑!


要使用 git rebase -i 执行此操作而不必 count 次提交(如 HEAD~20 中那样),请使用:

git log --decorate --oneline --graph

仔细查看您打算变基的提交。您将获得带有缩写哈希 ID 及其提交主题的提交的单行列表,以及提交图的 ASCII 绘图。确保它在您要复制的提交中没有分支合并模式(或者如果有,如果您丢弃所有合并也没关系)——在这种情况下,这意味着它只是一系列 * 标记在您打算复制和替换的提交之前。然后,代替 counting,使用:

git rebase -i <hash>

其中 hash 是您第一次提交的那个 不会 复制或修改。

请注意,即使您使用 old 分支名称,像这样的 rebase 的最终结果也是 新的一系列提交 识别它。这就是为什么它通常不是一个好主意:您要丢弃并替换的不仅是 您的 提交,还有其他人正在使用并仍在使用的其他提交。因此,他们 必须切换到这些新的副本,这些新副本也是你他们 提交的。

在这种情况下(功能分支有很多其他人的更改),我所做的是始终通过 git pull --rebase 将我未推送的提交保留在其他提交的 "top" 上。这将按服务器上的原样获取分支,并将我的本地提交放在最上面。请注意,这将更改我的本地分支历史记录,但不会更改远程分支历史记录,因此在推送时将 no 需要使用 --force :).

然后,当您准备好使用一次提交将您的工作发送到服务器时,您可以通过查找顶级服务器提交的哈希来简单地压缩,并且:

git reset --soft HASH_BEFORE_MY_FIRST_LOCAL_COMMIT

这将使您本地提交的所有更改都已暂存。您只需使用 git commit -m "..."git gui 或您喜欢的工具指定一条新消息来提交它们。请注意,此时您不会收到每条单独的消息,因此如果您需要它们,最好在执行 git 重置之前获取它们。

这种方法的缺点:当您使用 git pull --rebase git 时,将逐一应用您的每个本地提交。如果发生冲突,您将不得不解决它并使用 git rebase --continue。不利的一面是,根据本地提交的数量,您可能会多次发生冲突。