Хорошо, я думал, что это был простой сценарий мерзавца, что я пропускаю?
У меня есть master
филиал и feature
филиал. Я работаю над master
некоторыми, над некоторыми feature
, а потом еще над некоторыми master
. Я получаю что-то вроде этого (лексикографический порядок подразумевает порядок коммитов):
A--B--C------F--G (master)
\
D--E (feature)
У меня нет проблем с обновлением git push origin master
пульта master
, а также с git push origin feature
(когда он включен feature
) для сохранения удаленной резервной копии моей feature
работы. До сих пор у нас все хорошо.
Но теперь я хочу перебазировать feature
поверх F--G
коммитов на мастере, поэтому я git checkout feature
и git rebase master
. Все еще хорош. Теперь у нас есть:
A--B--C------F--G (master)
\
D'--E' (feature)
Проблема: в момент, когда я хочу сделать резервную копию новой перебазированной ветки feature
сgit push origin feature
, толчок отклоняется, поскольку дерево изменилось из-за перебазировки. Это можно решить только с помощью git push --force origin feature
.
Я ненавижу использовать, --force
не будучи уверенным, что мне это нужно. Так мне это нужно? Есть ли перебазирования обязательно означает , что следующий push
должен быть --force
FUL?
Эта ветвь функций не используется другими разработчиками, поэтому де-факто у меня нет проблем с принудительным нажатием, я не собираюсь терять какие-либо данные, вопрос более концептуальный.
git pull feature-branch
, это извлечение создаст новый коммит слияния (путем слияния удаленных и локальных версий ветви компонента). Так что либо вы получаете ненужное слияние после ребазинга, либо нажимаете--force
.push --force
это не проблема), чтобы сохранять историю коммитов линейной без каких-либо коммитов слияния вообще.--force-with-lease
как предложил @hardev отличный вариантВместо использования -f или --force разработчики должны использовать
Почему? Потому что он проверяет удаленную ветку на наличие изменений, что является хорошей идеей. Давайте представим, что Джеймс и Лиза работают над одной и той же веткой функций, а Лиза выдвинула коммит. Джеймс теперь перебазирует свою местную ветку и отклоняется при попытке подтолкнуть. Конечно, Джеймс думает, что это связано с перебазированием и использует --force, и переписал бы все изменения Лизы. Если бы Джеймс использовал --force-with-lease, он бы получил предупреждение о том, что кто-то другой совершил коммиты. Я не понимаю, почему кто-то будет использовать --force вместо --force-with-lease при нажатии после ребазинга.
источник
git push --force-with-lease
спас мне кучу.--force-with-lease
решается проблема использования--force
Я бы использовал вместо "checkout -b", и это легче понять.
когда вы удаляете, вы не можете нажать на выходящую ветку с другим идентификатором SHA. Я удаляю только удаленную ветку в этом случае.
источник
push --force
, что и способ предотвращения мерзавцев--force
. Таким образом, я не думаю, что это когда-либо хорошая идея - либо репозиторий разрешаетpush --force
, либо по уважительной причине отключает его. Ответ Наби более уместен, если--force
он отключен в удаленном репо, так как он не рискует потерять коммиты от других разработчиков или иным образом вызвать проблемы.Одно из решений этой проблемы - сделать то, что делает сценарий слияния msysGit: после слияния слить в старый заголовок
feature
с-s ours
. В итоге вы получите граф фиксации:... и ваш толчок
feature
будет ускоренной.Другими словами, вы можете сделать:
(Не проверено, но я думаю, что это правильно ...)
источник
git rebase
(вместо слиянияmaster
обратно с вашей веткой функций) - создание чистой истории линейных коммитов. С вашим подходом история становится еще хуже. И поскольку перебазирование создает новые коммиты без какой-либо ссылки на их предыдущие версии, я даже не уверен, что результат этого слияния будет адекватным.merge -s ours
, что он искусственно добавляет родительскую ссылку к предыдущей версии. Конечно, история не выглядит чистой, но спрашивающий, кажется, особенно обеспокоен необходимостью толкатьfeature
ветку, и это обходит это. Если вы хотите перебазировать, это более или менее один или другой. :) В целом, я думаю, это интересно, что проект msysgit делает это ....ours
стратегию, но думал, что она применима только к конфликтным ситуациям, автоматически решая их, используя изменения в нашей ветке. Оказалось, это работает по-другому. И работать таким образом, это очень полезно, если вам нужна перебазированная версия (например, для сопровождающего репо, чтобы применять ее корректноmaster
), но вы хотите избежать принудительного нажатия (если по какой-то причине многие другие ppl используют вашу ветку функций).Может быть, а может и нет, что в этой ветке есть только один разработчик, который сейчас (после ребазинга) не соответствует источнику / функции.
В качестве такового я бы предложил использовать следующую последовательность:
Да, новая ветка, это должно решить эту проблему без --force, что, на мой взгляд, является основным недостатком git.
источник
Мой способ избежать принудительного нажатия - создать новую ветку и продолжить работу над этой новой веткой и после некоторой стабильности удалить старую ветку, которая была перебазирована:
источник
Другие ответили на ваш вопрос. Если вы перебазируете ветку, вам нужно будет принудительно нажать на эту ветку.
Rebase и общий репозиторий обычно не ладят. Это переписывает историю. Если другие используют эту ветку или имеют ответвления от этой ветви, то ребаз будет довольно неприятным.
В целом, rebase хорошо работает для местного филиала. Удаленное управление ветками лучше всего работает с явными слияниями (--no-ff).
Мы также избегаем слияния мастера в ветку функций. Вместо этого мы перебазируем на master, но с новым именем ветви (например, добавив суффикс версии). Это позволяет избежать проблемы перебазирования в общем хранилище.
источник
Что не так с
git merge master
наfeature
ветке? Это сохранит работу, которую вы имели, сохранив ее отдельно от основной ветки.Изменить: Ах, извините, не прочитал вашу проблему. Вам понадобится сила, поскольку вы выполнили
rebase
. Все команды, которые изменяют историю, будут нуждаться в--force
аргументе. Это отказоустойчивый, чтобы предотвратить потерю работы (старыеD
иE
будут потеряны).Итак, вы выполнили операцию,
git rebase
которая заставила дерево выглядеть (хотя частично скрытоD
иE
больше не находится в именованной ветви):Таким образом, при попытке протолкнуть новую
feature
ветку (сD'
иE'
в ней), вы потеряетеD
иE
.источник
Для меня работает следующие простые шаги:
После всего вышеперечисленного, мы также можем удалить ветку myFeature, выполнив следующую команду:
источник
Следующие работы для меня:
git push -f origin branch_name
и это не удаляет любой мой код.
Но, если вы хотите избежать этого, вы можете сделать следующее:
тогда вы можете выбрать все свои коммиты в новую ветку.
git cherry-pick COMMIT ID
а затем нажмите вашу новую ветку.источник
-f
это псевдоним для--force
, которого вопрос пытается избежать, если это возможно.Поскольку ОП понимает проблему, просто ищет более хорошее решение ...
Как насчет этого как практики?
Имейте в реальной ветке разработки функций (где вы никогда не делаете ребаз и форс-пуш, чтобы ваши коллеги-разработчики не ненавидели вас). Здесь регулярно берут эти изменения с основного слияния. История МессьеДа, сложнее, но жизнь проста, и никто не вмешивается в его работу.
Иметь вторую ветвь разработки функций, где один член команды функций регулярно выталкивает все функции, фактически перебазированные, действительно форсированные. Так что почти чисто на основе довольно недавнего мастер-коммита. По завершении функции нажмите эту ветку сверху мастера.
Для этого метода уже может быть имя шаблона.
источник