简体   繁体   English

GIT:从特定提交开始,还原所选的提交,释放,然后重新应用它们

[英]GIT: revert selected commits since a certain commit, release, then reapply them

There are a load of commits for two bugfixes X and Y pushed to a release branch in a remote repository. 对于XY的两个错误修正,有大量提交提交,这些修正已推送到远程存储库中的发行分支。 The last stable release from the branch was done after commit a . 在提交a之后,完成了分支的最后一个稳定版本。

在此处输入图片说明 Bugfix X is done but bugfix Y is still ongoing. 错误修正X已完成,但错误修正Y仍在进行中。 The x commits are mixed up with the y commits. x提交与y提交混在一起。

The original intention was to release bugfixes X and Y together, but things have changed and it's decided we need to release the fix for X right now . 初衷是为了释放错误修正XY在一起,但事情发生了变化,它的决定,我们现在需要释放X的修补程序。

Speaking conceptually this means I have to remove all the y commits and keep all the x commits since commit a - then release bugfix X from the branch - and then reapply all the y commits again so work can resume on bugfix Y . 从概念上讲,这意味着我必须删除所有自提交a以来的y提交,并保留所有x提交-然后从分支中释放bugfix X-然后重新应用所有y提交,以便可以在bugfix Y上恢复工作。

One solution I thought about is to just branch from commit a and cherry pick x1 , x2 and x3 to the new branch, then just release from there. 我想到的一个解决方案是,从commit a分支,然后选择x1x2x3到新分支,然后从那里释放。 However, unfortunately this isn't possible as I have to release from this branch and continue working on it afterwards (don't ask me why, I just do :)) 但是,不幸的是,这是不可能的,因为我必须从该分支中​​释放出来,然后再继续处理它(不要问我为什么,我只是这样做:))

This isn't a problem I've encountered before with GIT so I'm unsure what potential patterns there are for solving it. 这不是我以前使用GIT遇到的问题,因此我不确定有哪些潜在的模式可以解决它。 So, what is the most elegant way to achieve my goal? 那么, 实现目标的最优雅的方法是什么?

I want a solution that uses minimal steps, preserves the true history of the branch before it was applied ( ie I strictly cannot rebase! ), and does not requiring manual file editing, with the possible exception of merges. 我想要一个使用最少步骤的解决方案,在应用分支之前保留分支的真实历史记录( 即,我严格不能变基! ),并且不需要手动文件编辑(合并可能除外)。

The most elegant way is to rebase --interactive 最优雅的方法是重新设置--interactive

Update Since you clarified that this isn't even an option, clearly you have revert and cherry-pick left (like an accountant: no deletions, but 'counter-bookings'). 更新由于您已经澄清了甚至不是一个选择,因此显然您已经revert并左cherry-pick (就像会计师一样:没有删除,但有“柜台预订”)。

This can get tedious. 这可能会很乏味。 However, you can use UI's to your advantage. 但是,您可以使用UI来发挥自己的优势。 Or you can automate things: 或者您可以使事情自动化:

UPDATE I've made a complete self-contained demo Live on Coliru 更新我已经在Coliru上制作了完整的独立演示Live

If you can 'grep' the commits for issue-tracker IDs, you could automate things. 如果您可以“ grep”问题跟踪器ID的提交,则可以使事情自动化。 Here's a demo assuming you used ticket number #724 in the commit messages. 这是一个演示示例,假设您在提交消息中使用了票证编号#724 (Note how it limits the range of commits to grep by doing a..HEAD (replace a by the relevant commit-id or tag): (请注意,它如何通过执行a..HEAD (用相关的commit-id或标签代替a来限制对grep的提交范围:

$ culprits=$(git rev-list --grep='#724' a..HEAD)
$ do git revert --no-edit $culprits

now do your release! 现在释放您!

$ git tag RELEASE_20130913   # or, maybe, do the release immediately
    $ git cherry-pick $culprits 

if you mess up, just git reset --hard 'commit' (with 'commit' referring to the last commit before the first revert ). 如果您搞砸了,只需git reset --hard 'commit' ('commit'指的是第一次revert之前的最后一次提交)。


Original answer: 原始答案:

The most elegant way is to rebase --interactive 最优雅的方法是重新设置--interactive

git rebase -i a

Many git gui tools make it exceptionally easy to do this (TortoiseGit on windows, very nice). 许多git gui工具使执行此操作异常容易(Windows上的TortoiseGit,非常好)。 However, I have no trouble following the instructions on screen in the command-line version (which let's you 'edit rebase-plan' in a text editor). 但是,我完全可以按照命令行版本中的屏幕说明进行操作(让您在文本编辑器中“编辑变基计划”)。

So your rebase will come up with eg 因此,您的基准将提出例如

pick a comment1
pick x1 comment2
pick y1 comment3
pick x2 comment4
pick x3 comment5
pick y2 comment6

Just reorder: 只需重新排序:

pick a comment1
pick x1 comment2
pick x2 comment4
pick x3 comment5
pick y1 comment3
pick y2 comment6

Note This does rewrite history since after the x1 commit (but that's not released yet, and you can probably decide whether it's a problem with your co-workers who might have to rebase their changes onto the newer HEAD now). 注意:自从提交x1之后,这确实会重写历史记录(但是尚未发布,因此您可能可以确定同事是否有问题,他们可能现在必须将其更改基于新的HEAD)。 Just fair warning. 公正的警告。

And done! 并做了!


After the rebase, just tag the new revision x3 (with "comment5"), eg 重新设置基准后,只需标记新的修订版x3 (带有“ comment5”),例如

git tag release_20130912 HEAD~2

and release that . 然后放开那个 It will still be from the current branch, which already has the two y1 , y2 commits as well. 它仍将来自当前分支,该分支已经具有两个y1y2提交。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM