无法挑选一个提交到分支(坏对象错误)
Can't cherry pick one commit to a branch (bad object error)
OK,所以我们一般的git结构是我们有一个master分支,一个或多个release分支,然后是feature分支。所有主要开发都发生在功能分支中,但错误修复有时会直接提交到发布分支。
在将一些功能合并到发布分支时,出现了错误的合并,但直到后来提交了几个错误修复后我们才注意到它。一些功能分支在合并后被删除(我们将改变我们的工作流程以仅在将来发生实际发布后才执行)。如果它们没有被删除,我们将废弃发布分支并重做。
我现在正试图消除这个错误的合并。我在合并之前从发布分支创建了一个新的发布分支。
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 个)提交。但我不知道该怎么做。我认为 cherry-pick 是可行的方法,但当我尝试时,我得到:
$git cherry-pick fa4a761
错误:fa4a761:无法挑选 blob
致命:cherry-pick 失败
$ git cherry-pick 44923992349dae68d982dd305a289ba63f8f6d0b
fatal: bad object 44923992349dae68d982dd305a289ba63f8f6d0b
请注意,上面的散列是 copy/pasted 出 gitk,但它没有出现在我的任何分支的任何 git 日志中。
我也回去检查了,我现在尝试修复的所有提交都是一样的。我不确定这意味着什么,或者为什么它们会出现在 gitk 而不是 git 日志中(gitk 从哪里获取信息?)。
好的,更新时间。这是我遗漏的故事的其余部分。当我发现损坏的合并时,我从我们的中央仓库创建了一个新的仓库克隆到 "play with"。
事实证明,所有问题提交从未从存储库的原始副本推送到中央存储库。一旦我推送了这些提交,我就能够很好地修复所有问题。
似乎 git 认为 fa4a761
是 BLOB
(文件内容)而不是 COMMIT
的缩写 ID。
我假设您以可靠的方式获得了提交 ID,并且您没有输入错误。
这将是一个惊人的巧合,但我想知道你的目标提交 ID 的前 7 个字符是否与 BLOB
ID 的前 7 个字符匹配? (我猜想如果发生这种情况 git 会抛出一个错误,说缩写不明确,但我不确定,也没有简单的方法来测试它...)
因此您可以尝试使用提交 ID 的前 10 个 digit。或者您可以使用 old_release_branch~2
之类的表达式来标识发布分支上的倒数第 3 个提交,这样就不必正确复制提交 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
原来我只是个白痴
它不起作用,因为克隆的仓库中不存在未推送的提交。
在开始 "fixup" 分支之前,我已经将一个中央存储库的克隆存储库克隆到另一个目录中。丢失的提交实际上从未被推送到中央存储库,所以当然哈希不存在在克隆的仓库中。
您需要执行 git 获取以获取与本地同步的最新提交
git 获取
然后做
git cherry-pick
OK,所以我们一般的git结构是我们有一个master分支,一个或多个release分支,然后是feature分支。所有主要开发都发生在功能分支中,但错误修复有时会直接提交到发布分支。
在将一些功能合并到发布分支时,出现了错误的合并,但直到后来提交了几个错误修复后我们才注意到它。一些功能分支在合并后被删除(我们将改变我们的工作流程以仅在将来发生实际发布后才执行)。如果它们没有被删除,我们将废弃发布分支并重做。
我现在正试图消除这个错误的合并。我在合并之前从发布分支创建了一个新的发布分支。
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 个)提交。但我不知道该怎么做。我认为 cherry-pick 是可行的方法,但当我尝试时,我得到:
$git cherry-pick fa4a761
错误:fa4a761:无法挑选 blob
致命:cherry-pick 失败
$ git cherry-pick 44923992349dae68d982dd305a289ba63f8f6d0b
fatal: bad object 44923992349dae68d982dd305a289ba63f8f6d0b
请注意,上面的散列是 copy/pasted 出 gitk,但它没有出现在我的任何分支的任何 git 日志中。
我也回去检查了,我现在尝试修复的所有提交都是一样的。我不确定这意味着什么,或者为什么它们会出现在 gitk 而不是 git 日志中(gitk 从哪里获取信息?)。
好的,更新时间。这是我遗漏的故事的其余部分。当我发现损坏的合并时,我从我们的中央仓库创建了一个新的仓库克隆到 "play with"。
事实证明,所有问题提交从未从存储库的原始副本推送到中央存储库。一旦我推送了这些提交,我就能够很好地修复所有问题。
似乎 git 认为 fa4a761
是 BLOB
(文件内容)而不是 COMMIT
的缩写 ID。
我假设您以可靠的方式获得了提交 ID,并且您没有输入错误。
这将是一个惊人的巧合,但我想知道你的目标提交 ID 的前 7 个字符是否与 BLOB
ID 的前 7 个字符匹配? (我猜想如果发生这种情况 git 会抛出一个错误,说缩写不明确,但我不确定,也没有简单的方法来测试它...)
因此您可以尝试使用提交 ID 的前 10 个 digit。或者您可以使用 old_release_branch~2
之类的表达式来标识发布分支上的倒数第 3 个提交,这样就不必正确复制提交 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
原来我只是个白痴
它不起作用,因为克隆的仓库中不存在未推送的提交。
在开始 "fixup" 分支之前,我已经将一个中央存储库的克隆存储库克隆到另一个目录中。丢失的提交实际上从未被推送到中央存储库,所以当然哈希不存在在克隆的仓库中。
您需要执行 git 获取以获取与本地同步的最新提交
git 获取
然后做
git cherry-pick