Как полностью заменить основную ветку в Git из другой ветки?

В моем репозитории Git есть две ветки:

  1. master
  2. seotweaks (изначально создан из master)

Я создал seotweaks с намерением быстро объединить его обратно в master. Однако это было три месяца назад, и код в этой ветке на 13 версий опережает master.

Он фактически стал нашей рабочей главной ветвью, поскольку весь код в master сейчас более или менее устарел.

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

Вы знаете, как я могу заменить все содержимое ветки master содержимым seotweaks?

Я мог бы просто удалить все в master и объединить, но это не похоже на лучшую практику.


person Jason    schedule 19.05.2010    source источник
comment
re: точный дубликат флага - это может быть правдой, но ответ ergosys ниже лучше, чем принятый ответ на этот вопрос, ИМО   -  person mikermcneil    schedule 19.12.2012
comment
обратите внимание, что он может быть объявлен дубликатом, но это первое попадание в веб-поиск для git delete branch master   -  person peterk    schedule 09.07.2015
comment
Эти моменты редко имеют значение для преданного фанатика-дубликата.   -  person geotheory    schedule 26.04.2016
comment
Кроме того, этот вопрос лучше сформулирован, и в нем отсутствует путаница, вызванная дополнительным комментарием, добавленным к вопросу после того, как ответы были начаты.   -  person Rob Osborne    schedule 10.05.2016
comment
Вы также можете проверить это решение stackoverflow.com/a/3790682/1770571   -  person Salma Gomaa    schedule 04.03.2019
comment
Есть простой способ использовать checkout, если и только если вас не беспокоит история фиксации seotweaks. Сначала переключитесь на главную ветку, затем запустите, git checkout seotweaks -- * затем запустите, git commit -m "Replaced contents of master with seotweaks" наконец запустите git push   -  person learner    schedule 17.09.2019


Ответы (5)


Вы должны иметь возможность использовать "нашу" стратегию слияния для перезаписи мастера с помощью таких уязвимостей:

git checkout seotweaks
git merge -s ours master
git checkout master
git merge seotweaks

Результат должен быть вашим хозяином, теперь по сути seotweaks.

(-s ours - сокращение от --strategy=ours)

Из документации о «нашей» стратегии:

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

Обновление из комментариев: если вы получили фатальный результат: refusing to merge unrelated histories, измените вторую строку на это: git merge --allow-unrelated-histories -s ours master

person ergosys    schedule 19.05.2010
comment
Это также отмечает место, где вы слились визуально (gitk --all или git log --all --graph). С этого момента последующие слияния будут включать в себя коммиты. - person Adam Dymitruk; 13.10.2010
comment
Может быть, уже слишком поздно добавлять этот вопрос, но что в этом не так: git checkout master; git merge -s theirs seotweaks - сохраняет пару шагов. - person Subu Sankara Subramanian; 22.09.2011
comment
@Subu Subramanian, такого варианта нет. См. repo.or.cz/w/ git.git / blob / HEAD: / Documentation / - person ergosys; 08.10.2011
comment
@ergosys, есть рекурсивный - person Joel Berger; 17.10.2011
comment
@Joel Berger, параметры рекурсивного слияния будут смешивать две ветки, отдавая предпочтение их или нашей только в случае конфликта. Таким образом, вы получите изменения из обеих веток. - person ergosys; 21.10.2011
comment
Это было особенно полезно, так как я ранее слил свою ветку в master, а затем отменил изменения, сделанные слиянием в основной ветке. Затем мне пришлось внести изменения, внесенные в основное руководство (патч) в другой моей ветке. Другая ветка стала новым хозяином, но мне нужно это изменить. Работал как шарм. Большое тебе спасибо! - person Thomas; 06.01.2012
comment
Это сработало как шарм. Смотрел на некоторые, казалось бы, сложные ответы в другом месте на SO. - person Alfie Hanssen; 06.03.2012
comment
У меня это не работает. Когда я делаю git merge -s ours master из другой ветки, я получаю уже обновленную версию. Что еще я могу попробовать? - person elsurudo; 09.03.2012
comment
@elsurudo Вероятно, это не ошибка: stackoverflow.com/a/634575/240633 - person ergosys; 04.05.2012
comment
@ergosys Не могли бы вы пояснить, что вы имеете в виду под словом «по существу»? Есть ли крайний случай, когда это не сработает? - person nextgentech; 04.02.2013
comment
Я не увиливал. Мне не известны такие случаи. - person ergosys; 04.02.2013
comment
Поскольку я работаю с удаленными ветками, мне нужно нажимать после каждого слияния? - person Eric; 24.01.2014
comment
У меня не сработало - person pratnala; 20.03.2014
comment
Я столкнулся с той же проблемой, что и оригинал, и этот подход заменил master моей желаемой веткой в течение 2 минут. Спасибо. - person Dave Collier; 27.03.2014
comment
Стратегия переименования, опубликованная ниже @ZelluX, лучше решает эту проблему. Этот ответ просто объединит очищенную ветку поверх существующего мастера. - person Milimetric; 13.05.2014
comment
@ergosys Есть ли в этом подходе какие-либо преимущества перед методом переименования ветвей ZelluX? Позже, когда вы посмотрите на слияние, это выглядит довольно вводящим в заблуждение, но, возможно, у подхода с переименованием есть недостаток? - person golddove; 17.06.2014
comment
Помимо ответа VonC, который вызывает некоторые проблемы, вы не сохраняете никаких неконфликтных изменений от старого мастера при переименовании. Вы можете не возражать, это зависит от ситуации. - person ergosys; 17.06.2014
comment
Мне нравится это решение, потому что оно сохраняет изменения локально для проверки перед заменой мастера !!! - person KateYoak; 23.05.2015
comment
Просто вау!! Можем ли мы добавить это в документацию GIT ... Серьезно - person Rob; 04.06.2015
comment
Зачем нужны шаги 3 и 4, если вы уже заменили основную ветвь на шагах 1 и 2 - person thedoublejointedprince; 24.10.2015
comment
Работал у меня. Не забудьте нажать обе ветки, если вы пытаетесь исправить удаленное репо, такое как github или bitbucket. - person JamesQMurphy; 16.12.2015
comment
Это сохранило все коммиты на мастере :( Я сделал это неправильно? - person Stop Slandering Monica Cellio; 21.12.2015
comment
Выполнил эти шаги - похоже, что-то сделал локально, но этого не произошло. К счастью, я сначала сделал копию своего рабочего каталога в новой ветке - сравнил ее с основной веткой, которую я предположительно обновил. Ничего не обновлялось (типичный git). Удалил файлы в директории master-ветки (кроме .git), заменил ее работой в директории работой новой ветки, затем git add-ed и зафиксировал - готово. Урок: делайте полные резервные копии перед чем-либо git. - person JosephK; 07.01.2016
comment
это не работает. Теперь я должен разрешить конфликты. Не заменяет мастера. Не отличается от слияния двух веток. - person ssal; 27.01.2016
comment
это объединит мастер в вашу ветку ?? что не то, что вы хотите - вы хотите полностью заменить master на другую ветку - или я неправильно понял? - person serup; 03.05.2016
comment
Я сделал это, а потом сделал git push. Фактически основные коммиты исчезли и были заменены коммитами веток. Есть ли способ отменить эти команды? - person Renato; 22.03.2017
comment
@Renato вы можете увидеть, можете ли вы вернуться к предыдущему состоянию, используя reflog. См. gitready.com/intermediate/2009/02/09. / - person ergosys; 22.03.2017
comment
@elsurudo после переименования, простейшее решение - подтолкните своего локального мастера ветки разработки к удаленному мастеру ветки git push origin master:master stackoverflow.com/questions/2936652/ - person Michael Dimmitt; 09.05.2017
comment
Этот подход отлично сработал для меня. У нас была бета-ветка, которая рассматривалась как основная, и основная ветка, которую не трогали более года. Единственное, что я сделал немного по-другому, - это git push перед слиянием бета-версии с мастером. git checkout beta - ›git merge -s ours master -› git push - ›git checkout master -› git merge beta - ›git push - person Donuts; 10.05.2017
comment
Проще говоря, если вы не заботитесь о потере мастера, вы можете запустить git push -f origin seotweaks:master - person PiersyP; 15.02.2018
comment
Чтобы избежать необходимости в сообщении о фиксации: git merge -s ours --no-commit master - person Matt; 06.06.2018
comment
Когда я делаю второй шаг, я получаю fatal: refusing to merge unrelated histories. Что мне теперь делать? - person Udayaditya Barua; 08.08.2018
comment
Но почему сообщение фиксации слияния Merge branch 'master' into other вместо Merge branch 'other' into master? И почему эта фиксация присутствует в обеих ветвях? Нет смысла выполнять слияние в ветке other, поскольку эта ветвь должна быть той, которая объединяется в master. - person Iulian Onofrei; 20.08.2018
comment
Насколько я понимаю, это фактически объединило ветвь master с веткой other, а затем переместило вперед ветку master. - person Iulian Onofrei; 20.08.2018
comment
Если вы получили fatal: refusing to merge unrelated histories, измените вторую строку на это: git merge --allow-unrelated-histories -s ours master - person code4kix; 21.08.2018
comment
Это был единственный ответ, который действительно сработал ... Я пробовал примерно 20: \ - person ; 05.09.2018
comment
это все еще отлично работает в 2019 году: D - person Iamsodarncool; 13.01.2019
comment
Сохраняет ли этот подход историю первоначального мастера? - person ntaj; 24.09.2019
comment
Он все еще объединяет две истории веток ... Я хочу полностью заменить master на _2 _... - person BartusZak; 18.02.2020
comment
Это не может быть ответом, это ответ stackoverflow.com/a/2862606/415078 - person angularrocks.com; 21.02.2020
comment
Не лучший ответ. Это по-прежнему объединит изменения из мастера в вашу новую ветку и будет иметь непредсказуемые результаты. Лучше всего выполнить переименование, как указано ниже. - person NickJ; 14.04.2020
comment
До сих пор не понимаю, как эта штука работает, лол. После первого слияния seotweaks фактически остается прежним, а мастер остается прежним. Значит, после второго слияния мастер должен содержать оба изменения, не так ли? Отменяет ли последний коммит слияния основные изменения? - person Sergiy Ostrovsky; 08.05.2020
comment
Введите :q и нажмите enter, чтобы сохранить файл фиксации после git merge -s ours master. - person Reed; 15.07.2020
comment
git-scm.com/docs/git-merge# Документация / git-merge.txt-ours. Это не всегда будет работать, если цитировать источник Changes from the other tree that do not conflict with our side are reflected in the merge result. Это не сработало для меня, так как у меня были чистые слияния коммитов в моей ветке, которая перезаписывалась. - person NiharGht; 12.08.2020
comment
@NiharGht Ваша цитата взята из нашего рекурсивного письма, которое отличается. Посмотрите чуть ниже документацию, касающуюся только нашего варианта. - person Pooks; 11.09.2020

Как насчет использования git branch -m для переименования основной ветки в другую, а затем переименования ветки seotweaks в master? Что-то вроде этого:

git branch -m master old-master
git branch -m seotweaks master
git push -f origin master

Это может удалить фиксации в исходном мастере, проверьте исходный мастер перед запуском git push -f origin master.

person ZelluX    schedule 19.05.2010
comment
Извините, когда я запускаю это, изменения происходят только локально. Как я могу заставить это повлиять на удаленные ветки? Спасибо - person Jason; 19.05.2010
comment
@ Джейсон: Попробуй git push -f origin master - person Koraktor; 19.05.2010
comment
Это именно то, что сработало для меня, спасибо! :) - person Jimbo; 27.03.2013
comment
Это, вероятно, лучший способ выполнить принудительное обновление после полной замены мастера. - person Hrishi; 16.02.2014
comment
вы можете сделать это в два этапа: git branch -m oldbranch newbranch; git checkout mynewmaster; git checkout -b master; .... ну, все равно двое :-) - person Alejandro Moreno; 06.05.2014
comment
Возможно, стоит пояснить, что этот ответ, возможно, удаляет коммиты, которые были в исходной ветке master. В то время как решение ergosys выполняет правильное слияние и сохраняет всю историю в master. - person florisla; 28.08.2015
comment
Дерьмо, я только что потерял все коммиты в исходном мастере. - person moberme; 19.11.2015
comment
Я также нашел это: stackoverflow.com/a/13307342/339803 с использованием theirs - person redfox05; 28.04.2016
comment
@moberme вы можете сделать git checkout old-master && git push origin old-master, чтобы создать ветку со старым мастером. - person Sander Visser; 11.05.2016
comment
Завершите с помощью git push origin :seotweaks, чтобы удалить старую ссылку из источника. - person rfabbri; 02.12.2016
comment
Если вы используете этот метод и хотите сохранить обе ветки (например, если вы хотите принудительно отправить код из staging для замены master, но хотите сохранить обе ветки после), просто переименуйте обе ветки в их исходные имена после принудительного нажатия и вправо после этого выполните git checkout master и запустите git fetch --all и git reset --hard origin/master. Это заставит вашу локальную master историю выровняться с удаленной историей. - person nickang; 29.09.2017
comment
Это сработало на gitlab. Перед тем, как сделать это, вы должны выполнить следующее. git checkout seotweaks - person Sacky San; 17.05.2018
comment
Это на самом деле не работает ... Просто действительно испортило мое репо - person Eric; 23.08.2018
comment
Проголосовать против простого переименования ветвей, а не слияния - person blurfx; 29.11.2018
comment
Это то, что я искал, чтобы фактически полностью заменить master вместо слияния (и в заголовке действительно спрашивается, как заменить основную ветку). Но вместо последнего git push -f origin master я сделал вместо git branch -u origin/master настройку восходящего потока. В моем случае удаляемые изменения не были внесены в пульт. - person Daniel; 25.06.2019
comment
@Daniel поднимает хороший вопрос, чтобы действительно сделать это, вам нужно добавить git branch -u origin/master в микс, если исходная ветвь уже отслеживается удаленным устройством. - person Kevin Leary; 19.11.2019

Вы можете переименовать / удалить мастер на удаленном компьютере, но это будет проблемой, если многие люди основывали свою работу на удаленной основной ветке и вытащили эту ветку в свое локальное репо.
Это может быть не так, поскольку все похоже, работает над веткой "seotweaks".

В этом случае вы можете:
git remote --show может не работать. (Сделайте git remote show, чтобы проверить, как ваш удаленный объявлен в вашем локальном репо. Я предполагаю, что 'origin')
(Что касается GitHub, house9 комментирует: «Я пришлось сделать еще один шаг, нажать кнопку «Admin» на GitHub и установить для «Default Branch» значение, отличное от «master», а затем вернуть его обратно »)

git branch -m master master-old  # rename master on local
git push origin :master          # delete master on remote
git push origin master-old       # create master-old on remote
git checkout -b master seotweaks # create a new local master on top of seotweaks
git push origin master           # create master on remote

Но опять же:

  • если другие пользователи попытаются извлечь, в то время как мастер удален на удаленном компьютере, их запросы не удастся («нет такой ссылки на удаленном»)
  • когда мастер воссоздается на удаленном компьютере, pull будет пытаться объединить этот новый мастер на их локальном (теперь старом) мастере: множество конфликтов. На самом деле им нужно reset --hard подключить свой локальный мастер к удаленной / основной ветке, которую они будут извлекать, и забыть о своем текущем мастере.
person VonC    schedule 19.05.2010
comment
Спасибо за подробный ответ, когда я запускаю «git push remote: master», я получаю сообщение об ошибке - «remote» не похоже на репозиторий git. - person Jason; 19.05.2010
comment
@Jason: Я изменил это на origin, которое может быть именем по умолчанию, присвоенным вашему удаленному репо. - person VonC; 19.05.2010
comment
@VonC: Я пытаюсь сделать это в репозитории git-hub, но при попытке выполнить «git push origin: master» получаю сообщение «[удаленное отклонение] master (удаление текущей ветки запрещено)». Что касается того, почему я это делаю ... в основном я сильно перепутал вещи, импортировав два раза одни и те же патчи через интерфейс github и нажав командную строку, а затем вернув все к работе с помощью ручного слияния. После этого я также создал еще одну ветку с чистой историей, но уже поздно ... в любом случае. Поскольку он находится в моем личном экспериментальном репозитории, это должно быть затронуто только мной. - person kriss; 24.08.2011
comment
@kriss: GitHub по умолчанию откажется от любой перезаписи / удаления истории путем принудительной перезаписи: git push -f origin :master. - person VonC; 24.08.2011
comment
спасибо, это было большим подспорьем; Мне пришлось сделать один дополнительный шаг, нажать кнопку «Администратор» в github и установить «Ветвь по умолчанию» на что-то другое, кроме «master», а затем вернуть его обратно. - person house9; 12.10.2011
comment
@ house9: хороший момент. Я отредактировал свой ответ, чтобы включить этот шаг. - person VonC; 12.10.2011

Поскольку seotweaks изначально был создан как ответвление от master, объединение его обратно - хорошая идея. Однако, если вы находитесь в ситуации, когда одна из ваших веток на самом деле не является ветвью от master или ваша история настолько отличается, что вы просто хотите стереть ветку master в пользу новой ветки, над которой вы работали может это сделать:

git push [-f] origin seotweaks:master

Это особенно полезно, если вы получаете такую ошибку:

! [remote rejected] master (deletion of the current branch prohibited)

И вы не используете GitHub и не имеете доступа к вкладке «Администрирование», чтобы изменить ветку по умолчанию для вашего удаленного репозитория. Кроме того, это не приведет к простоям или условиям гонки, с которыми вы можете столкнуться при удалении мастера:

git push origin :master
person mholm815    schedule 25.07.2012
comment
Не работает на Heroku:! [отклонено] ‹new_branch› - ›ошибка мастера (без перемотки вперед): не удалось отправить некоторые ссылки на '‹some_git› .git' - person shaioz; 03.03.2014
comment
git push -f origin seotweaks: у меня работал мастер - person Tom Andersen; 14.01.2016
comment
Отличный ответ: принудительные нажатия показывают мерзавцу, кто здесь главный. - person nbloqs; 04.07.2017
comment
Для меня это был, безусловно, самый простой способ получить обширные изменения в рабочей ветке со множеством сложных конфликтов (из-за удаления и переименования папок) обратно в мастер. Я не знаю, подходит ли это для каждого случая (возможно, нет), но это полностью сработало для меня, просто перенеся все из ветки, которую я сделал, обратно в мастер (рабочая ветка остается после операции, но обе ветки кажутся теперь есть те же коммиты). - person Ben Stahl; 13.06.2019
comment
Как выглядит master история git после force push? Записываются ли все файлы на master, даже если они не были изменены на seotweaks? - person BartusZak; 18.02.2020

Я обнаружил, что это лучший способ сделать это (у меня была проблема с моим сервером, который не позволял мне удалить).

На сервере, на котором размещен репозиторий origin, введите следующее из каталога внутри репозитория:

git config receive.denyDeleteCurrent ignore

На вашей рабочей станции:

git branch -m master vabandoned                 # Rename master on local
git branch -m newBranch master                  # Locally rename branch newBranch to master
git push origin :master                         # Delete the remote's master
git push origin master:refs/heads/master        # Push the new master to the remote
git push origin abandoned:refs/heads/abandoned  # Push the old master to the remote

Вернемся на сервер, на котором размещен репозиторий origin:

git config receive.denyDeleteCurrent true

Кредит автору сообщения в блоге http://www.mslinn.com/blog/?p=772

person ScottGuymer    schedule 28.09.2012
comment
Для меня основная ветка была веткой по умолчанию, поэтому я изменил ветку по умолчанию на ветку «разработка», удалил главную ветку и снова создал мастер из нужной ветки. Позже, если вы захотите, вы можете снова сделать ветвь «master» веткой по умолчанию. - person Sharad; 11.06.2018
comment
Ссылка не работает, Доступ запрещен. - person Peter Mortensen; 19.08.2018
comment
Стыд. Я думаю, что блоги все еще существуют на его сайте. Просто битая ссылка :( - person ScottGuymer; 18.01.2019