以编程方式使用 git rebase -i

5
我写了一个使用git定期进行一系列提交的node模块。考虑到如果将这些提交分组到一个单独的提交中,那么提交将更好,我想使用“git rebase -i”将它们压缩成一个提交。
但是,压缩只在交互模式下才可能实现,这意味着当调用“git rebase -i”时需要手动编辑弹出的编辑器中的行。我想知道是否有可能通过编程方式执行此过程?例如,当用户调用“save”函数时,我的模块将进行一系列提交,然后自动将它们合并在一起。
更新:
为了更精确地描述我的操作,当调用“save”函数时,会传递一堆提交以发布。然后,我的模块将挑选这些提交并将它们放入“publish”分支中。这是一个单一的“publish”操作,但它会在“publish”分支上生成一堆提交。我想做的是将“publish”上的提交压缩,这样当我运行“git log”时,我只能看到“publish version 1”,“publish version 2”等,而不是每个发布操作5或10个提交。

1
为什么不使用 git commit --amend 命令来创建这些“最好分组”的提交呢? - user229044
@meagar 感谢回复,但这些提交实际上是被精选到另一个分支中的,事先无法知道哪些提交将被分组,直到它们被该过程精选。 - Xavier_Ex
@CharlesBailey 但是我如何在重置和提交时完成这个操作? - Xavier_Ex
1
如果您有第二个分支,可以将这些提交移动到该分支,然后使用 git merge --squash 将该分支合并回来。 - user229044
只需使用任何有意义的参数。我不知道你用什么逻辑来挑选/分组你的提交,所以很难给予具体的帮助。 - CB Bailey
显示剩余3条评论
1个回答

2

根据你更新问题后的情况,以下两个选项之一可能适用于你:


第一个(也是更简单的)情况是,未发布的工作始终是一系列单独的提交,并且已发布的工作在同一分支上,但稍微落后一些:

  • 你有一个unpublished分支和一个published分支。后者包含在前者内(即相对于前者落后了若干提交)。
  • “保存”操作意味着现在unpublished中的哈希值abcdef应该成为published的HEAD。
  • 它执行git checkout published && git merge --ff-only abcdef
  • 这将使published快进到该提交。

第二种情况是可以发布的提交不一定是线性序列。如果重新排序提交,则可能需要解决冲突,这会变得有点复杂。我会按以下方式解决:

  • 再次假设存在unpublishedpublished分支。
  • 保存操作包括一些来自unpublished的哈希值。
  • 它应该从当前published分支创建一个新的临时分支,例如publish-2013-04-15-001(新分支的名称基本上无关紧要,只要唯一/新即可)。
  • 对于应该保存的每个哈希值执行git cherry-pick <hash>。(如果有多个提交,则可能会出现冲突,需要以某种方式解决。)
  • 完成后,检出published分支。
  • 执行git merge --squash -m 'Publish version <n>' publish-2013-04-15-001
  • (可选)删除临时分支。

由于第二个选项引入了更多的复杂性,你可能想考虑其他选项来使发布过程更容易进行调试:

  • 我应该保留用于跟踪/记录的临时分支吗?
  • 合并后的分支是否可以保持各个提交分离(省略--squash)?
  • 如果是这样,你可以通过强制进行合并提交(--no-ff)来标识保存。

编辑:这里是使用--no-ff的示例。每个版本$N执行以下操作:

git checkout -b publish-$N published
# cherry-pick commits
git checkout published && git merge --no-ff publish-$N -m "Publish version $N"

example tig graph


谢谢你的回答,我认为临时分支是最接近我想要的方法,因为我想要进行的提交不一定是线性序列(由于我的项目的性质,冲突可以很容易地解决)。然而,我不太理解你更新的评论:你说的“通过强制合并提交- no-ff来识别保存”是什么意思? - Xavier_Ex
@Xavier_Ex 我已经更新了问题,并提供了一个示例拓扑,该选项将导致这种结果。 - cmbuckley
谢谢提供的图片,但在这种情况下,“--squash”和“--no-ff”有什么区别呢?据我理解,“--squash”会将所有提交压缩成一个,并创建一个单独的合并提交,而“--no-ff”则始终会创建一个单独的合并提交。我看不出有什么区别...? - Xavier_Ex
“--squash” 选项会将多个非合并提交压缩成一个提交,提交信息为“发布版本 $N”。在此情况下,不会有合并操作,也无法后续分离各个单独的提交(即取消压缩)。而使用“--no-ff” 选项则会保留原始提交和信息,并通过一个合并提交将它们组合在一起。 - cmbuckley
看一下这个示例图片,来解释--no-ff的作用。合并提交可能本身不会引入任何代码更改,但只是标识它具有多于1个父级(即将A合并到B时,其父提交既包括A又包括B)。Squash将所有单独的提交合并为一个变更集。 - cmbuckley
显示剩余2条评论

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