压缩推送 Git 提交的最佳做法是什么

What is the best practice to squash pushed Git commits

到目前为止,我一直在进行交互式 git 变基相当频繁:未推动的工作,或我确信我是唯一可以从事的推动工作。

我知道压缩提交和整体重写历史在协作工作时可能会很棘手。

尽可能减少疼痛的最佳做法是什么?

如果我压缩一些提交并推送,当他拉取时,回购在同事的站上会是什么样子?

  1. 当他什么都没做,只需要更新时?
  2. 他什么时候做了一些改变,并且在提交之前想要更新?

我知道重写历史的概念本身就是一个永无止境的争论,但我只是在这里寻找一个技术解决方案来处理这个问题。

What is the best practice to do it with as little pain as possible?

最好的做法是避免它。

正如 ElpieKay 所建议的,拥有一个 "release branch" 是一个很好的做法,它的历史是安全的,事情是稳定的,但也有 "development/feature branches" 在那里你可以做任何你想做的事情,直到你merge/rebase 他们再次进入你稳定的 master 分支。

回答您的问题:

  1. When he has done no change and just needs to update?

当没有改变任何东西并拉动时,git 将把遥控器的历史记录作为正确的(因为显然有人 --force-pushed,所以它必须是正确的。)所以它只会覆盖您的协作者的工作并使提交历史与远程服务器上的历史相匹配。它会显示一条附加消息,例如 force update,就像您强制推送某些内容时一样。

请注意,旧提交不会真正被删除 - 只是 "hidden",因为它们与提交图的其余部分没有链接。因此,如果您突然需要再次访问 "deleted" 提交,只要您在某处拥有丢失提交的 SHA 哈希值,这就可能实现。 git 垃圾清理器会在对存储库进行一定数量的操作后删除无法访问的对象。

  1. When he did do some changes, and wants the update before committing himself?

这显然是最坏的情况。无论如何,通过提交您的更改(即使您以后想应用它们!),确保您拥有所有更改和分支的备份副本,创建一个临时的新副本

git add . ; git commit -am "Describe all my changes here" ; git branch backup

现在您的更改已安全地存储在备份分支中,您可以再次删除提交。

git reset --hard HEAD~

然后拉取当前分支

git pull

这应该可以在没有任何合并冲突的情况下工作,因为它基本上代表情况 #1,其中没有进行任何更改,它只会使本地历史记录与远程历史记录匹配。现在您可以通过再次应用您的更改(= backup 分支上的最新提交)再次应用您的更改。

git cherry-pick backup

显然,当远程存储库更新相同的代码行时,这可能会导致合并冲突。如果没有冲突,那么您可以删除 backup 分支。您的存储库是最新的,您的更改已应用到它之上。

但是,再次尝试避免这些情况。要么在合并之前 squash/rebase 在单独的功能分支中,要么让提交在合并后保持原样。