Не может вишня выбрать один коммит в ветке (ошибка плохого объекта) - PullRequest
0 голосов
/ 26 апреля 2018

ОК, поэтому наша общая структура git такова, что у нас есть основная ветвь, одна или несколько веток релиза, а затем функциональные ветки. Вся основная разработка происходит в ветвях функций, но исправления ошибок иногда фиксируются непосредственно в ветвях релиза.

При слиянии некоторых функций в ветке релизов произошло плохое слияние, но мы не заметили его, пока впоследствии не было исправлено несколько исправлений. Некоторые ветви функций были удалены после слияния (что мы изменим в нашем рабочем процессе только после фактического выпуска в будущем). Если бы они не были удалены, мы бы просто удалили ветку релиза и повторили ее.

Я сейчас пытаюсь устранить это плохое слияние. Я создал новую ветку релиза из ветки релиза до слияния.

git checkout <hash prior to merge>
git checkout -b new_release_branch
git merge feature_branch_which_resulted_in_bad_merge_before

Эта ветвь теперь так, как нам нужно, но мне все еще нужно внести несколько (менее 5) коммитов, которые были сделаны для release_branch после неудачного слияния. Но я не могу понять, как это сделать. Я думал, что вишня - это путь, но когда я пытаюсь, я получаю:

$ git cherry-pick fa4a761
ошибка: fa4a761: не могу выбрать объект BLOB
фатальный: вишня не удалась

$ git cherry-pick 44923992349dae68d982dd305a289ba63f8f6d0b
fatal: bad object 44923992349dae68d982dd305a289ba63f8f6d0b

Обратите внимание, что вышеприведенный хеш скопирован / вставлен из gitk, но он не отображается ни в одном журнале git ни для одной из моих веток.

Я также вернулся и проверил все коммиты, которые я сейчас пытаюсь исправить, и они все одинаковые. Я не уверен, что это значит или почему они будут отображаться в gitk, а не в git log (где gitk получает информацию?).


ОК, время обновления. Вот остальная часть истории, которую я пропустил. Когда я обнаружил нарушенное слияние, я создал новый клон репо для «игры с» из нашего центрального репо.

Оказывается, что все проблемные коммиты никогда не были перенесены из оригинальной копии репо в центральное репо. Как только я нажал эти коммиты, я смог все исправить.

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

Оказывается, я просто идиот.

Это не работает, потому что в клонированном репо не существует фиксированных коммитов.

Я сделал клон репо из центрального репозитория в другой каталог, прежде чем начал "исправлять" ветку ". Отсутствующие коммиты фактически никогда не передавались в центральное репо, поэтому, конечно, хэши не существуют в клонированном репо .

0 голосов
/ 27 июня 2019

вам нужно выполнить git fetch, чтобы синхронизировать последние коммиты с локальными

git fetch

тогда делай

мерзавец вишня

0 голосов
/ 26 апреля 2018

Похоже, git думает, что fa4a761 - это сокращенный идентификатор для BLOB (содержимого файла), а не для COMMIT.

Я предполагаю, что вы получили идентификатор фиксации надежным способом, и что вы не просто набрали его неправильно.

Это было бы ошеломляющее совпадение, но мне интересно, совпадают ли первые 7 символов идентификатора вашей целевой фиксации с первыми 7 символами идентификатора BLOB? (Я бы догадался, если бы это произошло, git выдаст ошибку, сказав, что аббревиатура была неоднозначной, но я не уверен и у меня нет простого способа проверить это ...)

Так что вы можете попробовать использовать, скажем, первые 10 цифр идентификатора коммита. Или вы можете использовать выражение, подобное old_release_branch~2, для определения 3-го до последнего коммита в ветке релиза, чтобы не пришлось правильно копировать значения идентификатора коммита.

Еще один вариант, который может подойти для вашего случая, а также, во-первых, избавит вас от необходимости делать так много с ID фиксации, - это использовать rebase вместо cherry-pick. Это хороший вариант, если вы хотите диапазон коммитов, которые не являются слияниями. Например, звучит так, как будто у вас есть серия «исправлений», не связанных с слиянием, между неудачным слиянием (которое вы воссоздали) и старой веткой.

git rebase --onto new_release_branch <bad_merge> old_release_branch

В этой команде <bad_merge> может быть идентификатором старого коммита слияния или любым выражением, которое преобразуется в коммит слияния. Например, если у вас было 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
...