好的,所以我们的一般git结构是我们有一个主分支,一个或多个发布分支,然后是功能分支。所有主要开发都发生在功能分支中,但错误修复有时会直接提交到发布分支。
虽然将一些功能合并到一个发布分支中,但是有一个糟糕的合并但我们没有注意到它,直到之后提交了几个错误修正。合并后删除了一些功能分支(我们将改变我们的工作流程,只有在将来发生实际发布后才会这样做)。如果它们没有被删除,我们只需要废弃发布分支并重做它。
我现在正试图消除这种糟糕的合并。我在合并之前从发布分支创建了一个新的发布分支。
git checkout <hash prior to merge>
git checkout -b new_release_branch
git merge feature_branch_which_resulted_in_bad_merge_before
这个分支现在是我们想要它的方式但是我仍然需要引入在错误合并之后对release_branch进行的少量(少于5次)提交。但我无法弄清楚该怎么做。我认为樱桃选择是要走的路,但是当我尝试时,我得到了:
$ git cherry-pick fa4a761
错误:fa4a761:不能樱桃选择blob
致命的:樱桃挑选失败
$ git cherry-pick 44923992349dae68d982dd305a289ba63f8f6d0b
fatal: bad object 44923992349dae68d982dd305a289ba63f8f6d0b
请注意,上面的哈希是从gitk中复制/粘贴的,但它不会显示在我的任何分支的任何git日志中。
我也回去检查了所有我正在尝试修复的提交,它们都是一样的。我不确定这意味着什么或者为什么它们会出现在gitk中而不是出现在git log中(gitk在哪里获取信息?)。
好的,更新时间。这是我遗漏的故事的其余部分。当我发现破碎的合并时,我创建了一个新的repo克隆,以便从我们的中央仓库“玩弄”。
原来所有的问题提交从未从repo的原始副本推送到中央存储库。一旦我推动了这些提交,我就能很好地解决所有问题。
答案 0 :(得分:2)
似乎git认为fa4a761
是BLOB
(文件内容)的缩写ID,而不是COMMIT
。
我假设您以可靠的方式获得了提交ID,并且您不会错误地输入它。
这将是一个惊人的巧合,但我想知道你的目标提交ID的前7个字符是否匹配BLOB
ID的前7个字符? (我会猜到,如果发生这种情况,git会抛出一个错误,说缩写是不明确的,但我不确定,并且没有一种简单的方法来测试它......)
因此,您可以尝试使用提交ID的前10位数字。或者您可以使用类似old_release_branch~2
的表达式来标识发布分支上的倒数第三个提交,以便不必正确复制提交ID值。
可能适合您的情况的另一个选项,也是首先要避免必须处理提交ID,使用rebase
代替cherry-pick
。如果您想要一系列不合并的提交,这是一个不错的选择。例如,听起来你在糟糕的合并(你已经重新创建)和旧的分支提示之间有一系列非合并的“bugfix”提交。
git rebase --onto new_release_branch <bad_merge> old_release_branch
在此命令中,<bad_merge>
可以是旧合并提交的ID,也可以是解析为合并提交的任何表达式。例如,如果您在合并后有3个错误修正提交,则可以说old_release_branch~3
。
顺便说一下,如果功能分支没有被删除,你提到你会做一些不同的事情。我不完全确定我会看到你用不同的方式做什么因为最终你仍然需要从我认为的旧发布分支中提取直接提交的错误修正。但如果真的有所作为,您可以随时重新创建功能分支。当你删除一个合并的分支时,没有什么重要的东西真的丢失了。
例如,如果你有
... x -- M -- x -- x <--(release)
/
... A -- B -- O
你看到某些东西被合并到版本3提交之前,但我想功能分支已被删除。您可以从合并提交消息中检索其名称(假设您保留默认消息或将其替换为同样合理的消息),但如果不是,您仍然可以组成一个名称。
git checkout release~2^2
git branch replacement_feature_branch_name
答案 1 :(得分:0)
原来我只是个白痴。
它无效,因为克隆的仓库中不存在未推送的提交。
在开始“修复”分支之前,我已经从中央存储库创建了一个克隆存储库到另一个目录“。缺少的提交实际上从未被推送到中央存储库,所以当然克隆存储库中不存在哈希值
答案 2 :(得分:0)
您需要执行git fetch以获得与本地同步的最新提交
git fetch
然后做
git cherry-pick