Повторное повторное слияние в Git
У меня возникла проблема: у меня была ветвь 28s
для конкретной задачи в Git, которую я объединил в общем ветки develop
. Оказывается, я сделал это слишком быстро, поэтому я использовал git -revert, чтобы отменить слияние. Однако теперь пришло время объединить 28s
в develop
, но команда git -merge видит исходное слияние и счастливо объявляет, что все хорошо, а ветки уже объединены. Что мне теперь делать? Создайте "Revert" Revert "28s → develop" "commit"? Кажется, это не лучший способ сделать это, но я не могу представить ни одного другого на данный момент.
Как выглядит древовидная структура:
Ответы
Ответ 1
Вы должны "вернуть вспять". В зависимости от того, как вы вернули оригинал, это может быть не так просто, как кажется. Посмотрите официальный документ по этой теме.
---o---o---o---M---x---x---W---x---Y
/
---A---B-------------------C---D
разрешить:
---o---o---o---M---x---x-------x-------*
/ /
---A---B-------------------C---D
Но все ли это работает? Конечно, это так. Вы можете отменить слияние, и из чисто технический взгляд, мерзавец сделал это очень естественно и не имел никакого реального неприятности.
Он просто посчитал это переходом от "состояния до слияния" к "состояние после слияния", и все.
Ничего сложного, ничего странного, ничего действительно опасного. Git сделает это, даже не задумываясь об этом.
Так что с технической точки зрения, нет ничего плохого в том, чтобы отменить слияние, но с точки зрения рабочего процесса это то, что вы обычно должны пытаться избежать.
Если вообще возможно, например, если вы найдете проблему, которая была объединена в основное дерево, вместо того, чтобы отменить объединение, постарайтесь:
- разделите проблему на ветки, которую вы объединили, и просто исправьте ее,
- или попытайтесь отменить отдельный коммит, который вызвал его.
Да, это сложнее, и нет, это не всегда будет работать (иногда ответ: "Ой, я действительно не должен был слить это, потому что это не было готово, а мне действительно нужно отменить все слияния "). Итак, тогда вы на самом деле следует отменить слияние, но когда вы хотите повторно слить, вы Теперь нужно сделать это путем возврата назад.
Ответ 2
Предположим, что у вас есть такая история
---o---o---o---M---W---x-------x-------*
/
---A---B
Где A, B не удалось зафиксировать, а W - вернуть M
Итак, прежде чем я начну исправлять найденные проблемы, я делаю вишневый выбор W для моей ветки
git cherry-pick -x W
Затем я возвращаю W commit на моей ветке
git revert W
После этого я могу продолжить исправление.
Последняя история может выглядеть так:
---o---o---o---M---W---x-------x-------*
/ /
---A---B---W---W`----------C---D
Когда я отправляю PR, он ясно покажет, что PR отменяет возврат и добавляет новые коммиты.
Ответ 3
Чтобы вернуть реверс, не слишком сильно закручивая рабочий процесс:
- Создайте локальную копию мусора для разработки
- Отменить повторную фиксацию на локальной копии разработки
- Слейте эту копию в свою ветку функций и нажмите на свою ветку функций на свой сервер git.
Теперь ваша ветка функций должна быть объединена как обычно, когда вы к ней готовы. Единственным недостатком здесь является то, что у вас будет несколько дополнительных слияний/повторов в вашей истории.
Ответ 4
Чтобы отменить возврат в GIT:
git revert <commit-hash-of-previous-revert>
Ответ 5
Вместо использования git-revert
вы могли бы использовать эту команду в ветке devel
для выбросить (отменить) неправильную фиксацию слияния (вместо того, чтобы просто вернуть ее).
git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE
Это также соответствующим образом отрегулирует содержимое рабочего каталога. Будьте осторожны:
- Сохраните изменения в ветке разработки (с неправильного слияния), потому что они
также будет стираться с помощью
git-reset
. Все фиксации после того, что вы указываете как
аргумент git reset
исчезнет!
- Кроме того, не делайте этого, если ваши изменения уже были вытащены из других репозиториев
потому что reset будет переписывать историю.
Я рекомендую внимательно изучить man-страницу git-reset
, прежде чем пытаться это сделать.
Теперь, после reset, вы можете повторно применить свои изменения в devel
, а затем сделать
git checkout devel
git merge 28s
Это будет реальное слияние от 28s
в devel
, как и исходное (которое теперь
стирается из истории git).
Ответ 6
Я только что нашел этот пост, столкнувшись с той же проблемой. Я нахожу это выше, чем страшно, чтобы сделать reset hards и т.д. Я в конечном итоге удалю то, чего я не хочу, и не смогу вернуть его.
Вместо этого я проверил фиксацию, я хотел, чтобы ветка вернулась, например. git checkout 123466t7632723
. Затем преобразуется в ветвь git checkout my-new-branch
. Затем я удалил ветку, в которой я больше не хотел. Конечно, это будет работать, только если вы сможете выбросить ветку, которую вы испортили.
Ответ 7
Я бы предложил вам выполнить следующие шаги, чтобы отменить возврат, скажем, SHA1.
git checkout develop #go to develop branch
git pull #get the latest from remote/develop branch
git branch users/yourname/revertOfSHA1 #having HEAD referring to develop
git checkout users/yourname/revertOfSHA1 #checkout the newly created branch
git log --oneline --graph --decorate #find the SHA of the revert in the history, say SHA1
git revert SHA1
git push --set-upstream origin users/yourname/revertOfSHA1 #push the changes to remote
Теперь создайте пиар для users/yourname/revertOfSHA1
ветки users/yourname/revertOfSHA1
Ответ 8
- создайте новую ветвь при коммите до первоначального слияния - назовите его 'Develop-Base'
- выполнить интерактивную перебазировку 'Develop' поверх 'Develop-Base' (даже если она уже на вершине). Во время интерактивного перебазирования у вас будет возможность удалить как коммит слияния, так и коммит, который отменил слияние, т.е. удалить оба события из истории git
На этом этапе у вас будет чистая ветвь "разработки", в которую вы можете объединить свой набор функций, как вы это делаете регулярно.