Очистить ветку git master и перенести коммит в новую ветку?
У меня есть клон репозитория на Github, в котором я создал новую функцию для апстрима. Проблема в том, что я сделал это в своей основной ветке, которая также содержит другие вещи, которые я извлек из других клонов. Это полностью сломало мою способность создать разумный запрос на получение.
Поэтому я хочу сделать следующее:
- Восстановите мою ветку master, чтобы она была точно такой же, как и в основной ветке
- Создать новую ветку.
- Переместить некоторые из моих старых коммитов в новую ветку.
- Создайте запрос извлечения из ветки.
И в будущем я буду выполнять всю свою работу в ветвях и создавать запросы извлечения из них, оставляя свою основную ветвь в покое и просто объединяя все, что приходит из восходящего потока.
Мои вопросы:
- Это разумный подход?
- Как бы я на самом деле сделал шаги 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
удаленные изменения без их фактического применения. Делает жизнь намного проще.
git reset origin/master
git checkout -b new-branch
git cherry-pick <hash>
за каждый коммит- создайте свой запрос на получение.
В качестве альтернативы вы можете сделать:
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