以编程方式使用git rebase -i [英] programmatically use git rebase -i
问题描述
我编写了一个节点模块,该模块使用git进行不时的提交.考虑到将提交分组为一个提交会更好,我想使用"git rebase -i"将它们压缩为一个.
I wrote a node module that uses git to make a bunch of commits from time to time. Considering the commits are better if grouped into one single commit, I'd like to use "git rebase -i" to squash them into one.
但是,只有在交互模式下才可以进行压缩,这意味着我需要在调用git rebase -i时弹出的编辑器中手动编辑行.我想知道是否可以通过编程方式执行此过程吗?因此,例如,当用户调用保存"功能时,我的模块将进行一系列提交,然后自动将它们压缩在一起.
However squashing is only possible in interactive mode, which means I need to manually edit the lines in the editor that pops up when "git rebase -i" is called. I would like to know if it is possible to do this process programatically? So for example when the user calls "save" function my module would make a bunch of commits, and then automatically squash them together.
更新
为了更精确地说明我在做什么,当调用保存"功能时,将传递一堆提交以进行发布".然后,我的模块将挑选那些提交并放入发布"分支.这是一个单独的发布"操作,但是会在发布"分支上生成一堆提交.我想做的是压缩发布中的提交,所以当我执行"git log"时,我看到的只是发布版本1",发布版本2"等,而不是每个发布操作5或10次提交.>
To be more precise of what I'm doing, when the "save" function is called, it is passed a bunch of commits to be "publish". My module will then cherry pick those commits and put them into the "publish" branch. This is a single "publish" action, but it generates a bunch of commits on the "publish" branch. What I wanna do is to squash the commits on the publish, so when I do "git log" all I see is "publish version 1", "publish version 2" etc, instead of 5 or 10 commits per publish action.
推荐答案
看到您对问题的更新后,以下两个选项之一可能会起作用,具体取决于您的用法:
After seeing your update to your question, one of the two options below may work, depending on your usage:
第一种(也是更简单的情况)是,您的未发布作品始终是单个提交序列,而已发布作品位于同一分支上,但又落后一点:
The first (and simpler) case is where your unpublished work is always a single sequence of commits, and the published work is on the same branch, but a bit further behind:
- 您有一个
unpublished
分支和一个published
分支.后者包含在前者之内(即,后面有一定数量的提交). - 保存操作意味着来自
unpublished
的哈希abcdef
现在应该是published
的HEAD. - 它执行
git checkout published && git merge --ff-only abcdef
. - 这会导致
published
快进该提交.
- You have an
unpublished
branch and apublished
branch. The latter is contained within the former (i.e. some number of commits behind). - The save action means that a hash
abcdef
fromunpublished
should now be the HEAD ofpublished
. - It performs
git checkout published && git merge --ff-only abcdef
. - This causes
published
to fast-forward to that commit.
第二个是可以发布的提交不一定是线性序列的地方.这变得有些复杂,就好像您要重新排序提交一样,您可能必须解决所发生的冲突.我将通过以下方式解决该问题:
The second is where the commits that can be published are not necessarily a linear sequence. This becomes a little more complicated as if you reorder commits, you may have to resolve conflicts that arise. I would solve that in the following way:
- 再次假设存在
unpublished
和published
分支. - 保存操作包含来自
unpublished
的一些哈希. - 它应该从当前的
published
分支中创建一个新的临时分支,例如publish-2013-04-15-001
(新分支的名称在很大程度上是无关紧要的,只要它是唯一的/新的即可). - 对应保存的每个哈希执行
git cherry-pick <hash>
. (如果有多个提交,这是您可能会发生冲突并且可能需要以某种方式解决它们的地方.) - 完成后,签出
published
分支. - 执行
git merge --squash -m 'Publish version <n>' publish-2013-04-15-001
. - (可选)删除临时分支.
- Assume again that there are
unpublished
andpublished
branches. - The save action comprises some hashes from
unpublished
. - It should create a new, temporary branch like
publish-2013-04-15-001
from the currentpublished
branch (the name of the new branch is largely irrelevant, as long as it's unique/new). - Perform
git cherry-pick <hash>
for each hash that should be saved. (If there are multiple commits, this is where you could get conflicts and may need to resolve them somehow.) - Once done, check out
published
branch. - Perform
git merge --squash -m 'Publish version <n>' publish-2013-04-15-001
. - (Optional) delete the temporary branch.
由于第二个选项带来了更多的复杂性,因此您可能还需要考虑其他一些选项,以便更轻松地调试已发布的过程:
Since the second option introduces more complication, there are other options that you might want to consider to make it easier to debug the published process:
- 我应该保留临时分支以进行跟踪/记录吗?
- 是否可以在合并分支上将各个提交分开保存(省去
--squash
)? - 如果是这样,则可以通过强制执行合并提交(
--no-ff
)来标识保存.
- Should I keep the temporary branches around for tracking/logging?
- Could the individual commits be kept separate on the merged branch (leave out
--squash
)? - If so, you could identify the save by forcing a merge commit (
--no-ff
).
编辑:这是使用--no-ff
的示例.每个版本$N
都执行以下操作:
EDIT: Here's an example using --no-ff
. Each version $N
does the following:
git checkout -b publish-$N published
# cherry-pick commits
git checkout published && git merge --no-ff publish-$N -m "Publish version $N"
这篇关于以编程方式使用git rebase -i的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!