合并具有相同消息的Git提交?

3
我可能滥用git,使用了它从未设计过的方式。我是一个单人团队的唯一开发者,在多台机器上进行开发。例如,我在A机器上编写代码,需要在B和C机器上测试(并重新编译)代码。我进行快速开发(例如,每分钟提交一次,然后转到B/C机器进行测试)。
因此,我的许多提交都有具体含义的消息,特别是我经常这样做:
A机器:
git add -u
git commit -m "work"
git push

机器 B/C

git pull
make
./run_tests

哦,不!它不能工作...回到机器A并在1分钟后进行另一次提交。

因此,正如您所想象的那样,我的git --log历史记录中有很多毫无价值的注释,只包含“work”。是否有一种方法可以自动组合所有具有相同消息的git提交,特别是将所有连续的-m“work”提交组合成一个大的-m“big work”提交。

谢谢。

明确起见,我的评论历史记录(追溯2年)如下:

work
work
work
work
OMG THIS actually works.
work
work
work
OMG we solved a huge problem... we should call this v1.0
work
work
work

我想将所有“work”消息自动压缩为以下内容:
work
OMG THIS actually works.
work
OMG we solved a huge problem... we should call this v1.0
work

etc...

您好, 关于我为什么这样滥用Git,基本上是因为我将其用作ctrl-s功能......我还在20台机器上进行开发,并需要一种有效的方式在每分钟左右更改后共享代码。 NFS并不是一个选择,因为我也在离线/硬防火墙等机器上工作...


请看一下 git rebase--autosquash 功能。 - krlmlr
1
...或者使用 git merge--squash 特性。 - krlmlr
你可以了解关于 git flow 模型的内容。 - sectus
2
@krlmlr,重新定位推送的提交并不是个好主意。 - sectus
2个回答

3

您没有滥用 git。在 git 中,这是绝对正常的情况。

我建议您在 A 上设置工作仓库(除了可能已存在的远程 origin),还要设置两个更多的远程 remote_Bremote_C。(在主机 BC 上,您设置一个相应的裸仓库。)

这样,您就可以在 A 上工作并使用 git push remote_B 将您的提交简单地推送到主机上。 - 您可以通过在远程仓库中添加一个小钩子来自动构建项目并运行测试,从而进一步自动化此过程。

这样一来,您只需推送即可立即查看结果,无需离开 A


现在回到您的实际问题:我首先强烈建议您使用更有意义的提交消息。- 您通常会在某个特定的主题上工作,或者尝试解决某个特殊的问题。- 给自己一个提示关于提交的内容。

一旦您的测试成功,使用 git rebase -i。 只要您没有更改上游分支(它可能指向 origin,并且只有在完成工作后才会将其推送到该处),git rebase -i 将仅显示您尚未推送的那些提交,并允许您按照需要组合、重新排序和重命名它们。 - 在这一点上,拥有一些有意义的提交消息非常有帮助,以便能够有意义地将它们组合在一起。

最后,当您满意结果时,请将您的工作推送到 origin,一切都很好。:)


2
您所描述的工作流程与 git-rebase 交互式模式手册中所描述的非常相似:

交互式变基意味着您有机会编辑要变基的提交。您可以重新排序提交,也可以删除它们(清理不良或不需要的补丁)。

[...]

如果您希望将两个或多个提交合并为一个提交,请使用“squash”或“fixup”命令替换第二个及后续提交的“pick”命令。如果这些提交有不同的作者,则合并的提交将归属于第一个提交的作者。合并提交的建议提交消息是第一个提交和那些使用“squash”命令的提交的提交消息的连接,但省略了使用“fixup”命令的提交的提交消息。

将git-rebase示例应用到您的情况中,您需要执行以下类似操作:
$ git rebase --interactive HEAD~13 # to fix last 12 commits

编辑器将启动,其中包含您当前分支中的所有提交:

pick deadaaa work
pick deadbbb work
pick deadccc work
pick deadddd work
pick deadeee OMG THIS actually works.
pick deadfff work
pick dead000 work
...

您需要做的是将要合并到上面的提交中的“pick”更改为“fixup”:
pick deadaaa work
fixup deadbbb work
fixup deadccc work
fixup deadddd work
pick deadeee OMG THIS actually works.
pick deadfff work
fixup dead000 work
...

清理完毕之后,最安全的做法是从其他机器重新克隆该代码库。因为在共享代码库上搞混提交(例如git rebase操作)是造成灾难的绝佳配方,特别是如果您试图自动化此过程。

编辑:当您控制所有副本的库时,这不应该成为问题。只需确保在对主分支进行修改之前所有副本都处于同步状态即可。修改完成后,使用强制推送/拉取更新所有副本,使它们再次处于同步状态。如果出现问题,“从上游rebase恢复”git-rebase中的man部分应该会有所帮助。


你能详细说明一下最后一部分吗?在我这样做之后,我可以将其推送到我的主git服务器吗?其他所有机器(例如B/C/D机器)都需要进行全新的克隆吗? - user2990078
@user2990078,克隆有点夸张了。只要您修改主分支的最新版本并将结果强制推送到主服务器,您只需从其余机器中拉取更新即可。 - dkz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接