Очистить ветку git master и перенести коммит в новую ветку?

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

Поэтому я хочу сделать следующее:

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

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

Мои вопросы:

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

9 ответов

Решение

Сделайте новую ветку, чтобы держать вещи

$ git branch old_master

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

$ git checkout old_master
$ git push origin old_master

Сброс локального мастера до фиксации, прежде чем вы начнете изменять материал

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

Объединить изменения от основного мастера

$ git pull upstream master

Теперь УДАЛИТЕ мастер по удаленному репо

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

$ git push origin :master

И воссоздай это

$ git push origin master

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

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

git branch mywork-orig master

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

git reset --hard origin/master

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

git checkout -b mywork

Внесите необходимые изменения (выберите их из mywork-orig и т. Д.) И отправьте запрос на это.

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

# 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 удаленные изменения без их фактического применения. Делает жизнь намного проще.

  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

Согласно git push вы можете использовать git push origin +dev:master чтобы:

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

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

Это должно позволить вам сделать ваш локальный мастер выглядеть так, как вы хотите, используя git rebase -i, затем отправьте результат в github.


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

@Novelocrat предложил почти такой же подход, как и я. Определенно создайте резервную ветку из текущего местоположения вашего 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 ветвь, вы, вероятно, не можете чертить много на новых ветвях функций, которые вы создаете. Вишни выбирают коммиты, которые вы можете, а затем просто (или не так просто;) воссоздайте те, которые вы не можете легко выбрать вишенками.

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

$ git pull +master:master
   From git://github.com/matthewmccullough/hellogitworld
   + 1d22ca0...2a52e96 master     -> master  (forced update)

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

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

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

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

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

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

git branch -m master my-bad-master

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

git pull origin master:master

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

git branch old-master master

В целях безопасности переведите ветку old-master в источник

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

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

Когда закончите, форсируйте новую ветку master до начала координат.

git push -f origin master:master
Другие вопросы по тегам