Очистить ветку git master и перенести коммит в новую ветку? - PullRequest
39 голосов
/ 06 мая 2011

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

Так что я хочу сделать следующее:

  1. Восстановить мою основную ветвь так, чтобы она была точно такой же, как и у восходящего главного.
  2. Создайте новую ветвь.
  3. Переместите некоторые из моих старых коммитов в новую ветвь.
  4. Создайте запрос извлечения из ветви.

Ив будущем я буду выполнять всю свою работу в ветвях и создавать запросы извлечения из них, оставляя свою основную ветвь в покое и просто объединяя все, что приходит из восходящего потока.

Мои вопросы:

  1. Это разумный подход?
  2. Как бы я на самом деле делал шаги 1 и 3?

Ответы [ 9 ]

64 голосов
/ 10 мая 2011

Создать новую ветку для хранения вещей

$ git branch old_master

Отправить на удаленное устройство для резервного копирования (только в случае)

$ git checkout old_master
$ git push origin old_master

Сбросить локальный мастер в коммит до того, как вы начали изменять вещи

$ git checkout master
$ git reset --hard 037hadh527bn

Объединение изменений из upstream master

$ git pull upstream master

Теперь УДАЛИТЬ master в удаленном репо

На github это не будет работать без первого запускав раздел администратора для ветки и временно установив ветку по умолчанию на что-то отличное от master, поскольку они пытаются защитить вас от сноса вещей.

$ git push origin :master

И воссоздать его

$ git push origin master

На github вы должны теперь установить ветку по умолчанию обратно на master

8 голосов
/ 06 мая 2011

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

git branch mywork-orig master

После этого выможете сбросить master в исходное состояние (при условии, что вы master извлечены):

git reset --hard origin/master

Затем вы можете создать собственную ветку с предполагаемыми изменениями:

git checkout -b mywork

Сделатьизменения, которые вы хотите (выберите их из mywork-orig и т. д.) и отправьте для этого запрос на извлечение.

4 голосов
/ 23 февраля 2013

Уже поздно, но никто не предложил этот гораздо более простой метод:

# make sure we're in master
git checkout master
# create new branch from current master
git branch tmp_master
# grab most recent changes from upstream w/o applying them
git fetch upstream
# force reset local master to match upstream/master
git reset --hard upstream/master

Вы сохранили свои локальные изменения в tmp_master и принудительно обновили master, чтобы соответствовать самому последнему upstream/master.Теперь, чтобы origin/master выглядело как upstream/master:

git push -f origin master

Теперь идите вперед и cherry-pick из коммитов, или rebase изменения поверх текущего master.После чего у вас уже будет ваша новая ветка devel.

То, что вы хотели сделать, вполне возможно, но не в том порядке, в котором вы просили.И казалось, что другие забыли, что вы можете fetch удаленные изменения, фактически не применяя их.Делает жизнь намного проще.

3 голосов
/ 06 мая 2011
  1. git reset origin/master
  2. git checkout -b new-branch
  3. git cherry-pick <hash> для каждого коммита
  4. создать запрос на получение.

В качестве альтернативы вы можете сделать:

  • git checkout -b new-branch
  • git rebase -i origin/master
  • (выбрать и выбрать коммиты)
  • git checkout master
  • git reset origin/master
2 голосов
/ 09 мая 2011

В соответствии с git push вы можете использовать git push origin +dev:master для:

Обновлять основную ветку исходного хранилища с помощью ветви dev, что позволяет выполнять обновления без ускоренной пересылки.Это может привести к зависанию коммитов без ссылок в репозитории origin.

Я не уверен, работает ли это с github.У меня нет ничего, что мне нужно уничтожить прямо сейчас.:)

Это должно позволить вам сделать ваш локальный мастер-вид таким, как вы хотите, используя git rebase -i, а затем перенести результат в github.Вы можете удалить главную ветку на github (git push origin :master), а затем снова заполнить ее из своего локального, исправленного, главного.У меня такое чувство, что github может помешать вам сделать это, если это ветка по умолчанию (как, вероятно, master ).Если это так, перейдите в раздел Admin для своего хранилища и временно измените значение по умолчанию на другую ветку.

1 голос
/ 09 мая 2011

@ Новелократ предложил почти такой же подход, как и я.Определенно создайте резервную ветку из текущего местоположения вашей master ветви:

git branch mywork-orig master

В вашем случае, я думаю, origin - это ваша ветвь github, а upstream - то, откуда вы разветвились.По этой причине, когда у вас выписан ваш локальный master, вы должны сделать:

git reset --hard upstream/master

Это сбросит его до значения upstream 's master.Затем вы также должны подтолкнуть его к своей ветке на github:

git push origin +master

Затем создать новые ветви из вашей недавно сброшенной ветви master, которая теперь должна быть такой же, как upstream/master:

git checkout -b mywork

Поскольку вы выполнили так много слияний в своей старой ветке master, вы, вероятно, не сможете особо выбирать новые создаваемые ветки функций.Вишни выбирают коммиты, которые вы можете, а затем просто (или не так просто;) воссоздайте те, которые вы не можете легко выбрать вишенками.

1 голос
/ 09 мая 2011

Если вы хотите, чтобы «master» выглядел как «remotes / origin / master», вы можете сделать принудительное извлечение.

$ git pull +master:master
   From git://github.com/matthewmccullough/hellogitworld
   + 1d22ca0...2a52e96 master     -> master  (forced update)
1 голос
/ 09 мая 2011

Вы можете отправить произвольное изменение, установленное на произвольную ссылку в репозитории git, с помощью команды git push. В этом случае вам нужно будет определить хэш набора изменений, к которому вы хотите вернуться, и установить его в качестве заголовка главной ветви в удаленном репозитории. Предполагая, что этот удаленный репозиторий называется origin, вы можете использовать следующее, где XXXX - это хэш изменения, к которому вы хотите вернуться:

git push -f origin XXXX:refs/heads/master

Переключатель -f принудительно внесет изменение, так как по умолчанию git не позволит вам вносить изменения не в fastforward в удаленный репозиторий, так как это может привести к серьезным проблемам, если другие репозитории были клонированы из вашего.

0 голосов
/ 08 ноября 2017

У меня есть логичный и максимально безопасный подход. Предположения:

  • У вас должны быть полномочия принудительно устанавливать обновления для мастера в источнике.
  • Предполагается, что никто другой не потянул ни один из узлов, которые собираются удалить.
  • Вы можете запретить обновления главной ветви на источнике, пока вы исправляете главную ветку локально.

Переместить / переименовать локальную ветку плохого мастера в my-bad-master.

git branch -m master my-bad-master

Обновите вашу локальную основную ветку, чтобы она соответствовала главной ветви источника.

git pull origin master:master

Сохранить основную ветку источника в ветке с именем old-master

git branch old-master master

В целях безопасности переведите ветвь старого мастера в исходное положение

git push origin old-master:old-master
checkout master

Внести любые изменения в основную ветку. !!!! Убедитесь, что в исходную ветку master не внесено никаких изменений, пока вы не закончите !!!!

Когда закончите, переведите новую главную ветвь в исходное положение.

git push -f origin master:master
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...