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

У меня есть две ветки в моем репозитории Git:

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

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

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

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

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

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

Комментарии к вопросу (6)
Решение

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

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

В результате ваш мастер должен стать по сути seotweaks.

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

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

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

Обновление из комментариев: Если вы получаете фатальное: отказ в слиянии несвязанных историй, то измените вторую строку на следующую: git merge --allow-unrelated-histories -s ours master.

Комментарии (39)

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

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

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

Комментарии (16)

Вы можете переименовать/удалить master на remote, но это будет проблемой, если многие люди основывали свою работу на удалённой ветке master и использовали эту ветку в своём локальном репо.
В данном случае это может быть не так, поскольку все, похоже, работают над веткой '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, пока мастер удален на удаленном, их pull будет неудачным ("нет такого ref на удаленном")
  • когда мастер воссоздается на удаленном, пользователь pull попытается объединить этот новый мастер с их локальным (теперь уже старым) мастером: много конфликтов. На самом деле им нужно reset --hard их локального мастера на ветку remote/master, которую они будут собирать, и забыть о своем текущем мастере.
Комментарии (6)

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

git push [-f] origin seotweaks:master

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

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

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

git push origin :master
Комментарии (4)

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

На сервере, на котором размещен репозиторий 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/?р = 772

Комментарии (3)