Сделайте текущую ветку Git главной веткой
У меня есть хранилище в Git. Я сделал ветку, затем сделал некоторые изменения как в мастере, так и в ветке.
Затем, спустя десятки коммитов, я понял, что ветвь находится в гораздо лучшем состоянии, чем мастер, поэтому я хочу, чтобы ветвь "стала" мастером и не обращала внимания на изменения в мастере.
Я не могу объединить это, потому что я не хочу сохранять изменения на мастере. Что я должен делать?
Дополнительно: в этом случае "старый" мастер уже push
-ed в другой репозиторий, такой как GitHub. Как это меняет вещи?
17 ответов
Проблема с двумя другими ответами состоит в том, что у нового мастера нет старого мастера в качестве предка, поэтому, когда вы нажимаете его, все остальные будут испорчены. Это то, что вы хотите сделать:
git checkout better_branch
git merge --strategy=ours master # keep the content of this branch, but record a merge
git checkout master
git merge better_branch # fast-forward master up to the merge
Если вы хотите, чтобы ваша история была немного понятнее, я бы порекомендовал добавить некоторую информацию в сообщение о коммите слияния, чтобы прояснить, что вы сделали. Измените вторую строку на:
git merge --strategy=ours --no-commit master
git commit # add information to the template merge message
Убедитесь, что все загружено в ваш удаленный репозиторий (GitHub):
git checkout master
Переписать "master" с "better_branch":
git reset --hard better_branch
Принудительно нажмите на ваш удаленный репозиторий:
git push -f origin master
Изменить: Вы не сказали, что подтолкнули к публичному репо! Это делает мир различий.
Есть два пути: "грязный" и "чистый". Предположим, что ваша ветка названа new-master
, Это чистый способ:
git checkout new-master
git branch -m master old-master
git branch -m new-master master
# And don't do this part. Just don't. But if you want to...
# git branch -d --force old-master
Это изменит конфигурационные файлы в соответствии с переименованными ветками.
Вы также можете сделать это грязным способом, который не будет обновлять файлы конфигурации. Это то, что происходит под капотом вышеупомянутого...
mv -i .git/refs/new-master .git/refs/master
git checkout master
Переименуйте ветку в master
от:
git branch -M branch_name master
Из того, что я понимаю, вы можете ветвить текущую ветку в существующую ветку. По сути это перезапишет master
с тем, что у вас есть в текущей ветке:
git branch -f master HEAD
После того, как вы это сделаете, вы можете нажать master
ветвь, возможно, здесь также требуется параметр force:
git push -f origin master
Нет слияний, нет длинных команд. Просто branch
а также push
- но, да, это перепишет историю master
филиал, так что если вы работаете в команде, вы должны знать, что вы делаете.
Кроме того, я обнаружил, что вы можете перенести любую ветку в любую удаленную ветку, поэтому:
# This will force push the current branch to the remote master
git push -f origin HEAD:master
# Switch current branch to master
git checkout master
# Reset the local master branch to what's on the remote
git reset --hard origin/master
Я нашел ответ, который хотел найти в записи блога. Замените основную ветку другой веткой в git:
git checkout feature_branch
git merge -s ours --no-commit master
git commit # Add a message regarding the replacement that you just did
git checkout master
git merge feature_branch
По сути, это то же самое, что и ответ Каскабель. За исключением того, что "опция", которую он добавил ниже своего решения, уже встроена в мой основной блок кода.
Так проще найти.
Я добавляю это как новый ответ, потому что, если мне понадобится это решение позже, я хочу, чтобы весь код, который я собираюсь использовать, был в одном блоке кода.
В противном случае я могу скопировать-вставить, а затем прочитать подробности ниже, чтобы увидеть строку, которую я должен был изменить - после того, как я уже выполнил ее.
Я нашел этот простой метод, чтобы работать лучше всего. Он не переписывает историю, и все предыдущие проверки филиала будут добавлены к мастеру. Ничего не потеряно, и вы можете ясно видеть, что произошло в журнале фиксации.
Цель: сделать текущее состояние "филиала" "мастером"
Работая над веткой, передайте и внесите изменения, чтобы убедиться, что ваши локальные и удаленные репозитории обновлены:
git checkout master # Set local repository to master
git reset --hard branch # Force working tree and index to branch
git push origin master # Update remote repository
После этого ваш мастер будет точно соответствовать состоянию вашего последнего коммита ветки, а в вашем журнале мастер коммитов будут показаны все проверки ветки.
Приведенные здесь решения (переименование ветки в "master") не настаивают на последствиях для удаленного репозитория (GitHub):
- если вы ничего не нажимали с момента создания этой ветви, вы можете переименовать ее и нажать без проблем.
- если у вас есть push master на GitHub, вам нужно будет "git push -f" новую ветку: вы больше не можете нажимать в режиме ускоренной перемотки вперед.
-f --force
Обычно команда отказывается обновлять удаленную ссылку, которая не является предком локальной ссылки, используемой для ее перезаписи. Этот флаг отключает проверку. Это может привести к потере коммитов удаленным репозиторием; используйте это с осторожностью.
Если другие уже извлекли ваше хранилище, они не смогут извлечь эту новую мастер-историю, не заменив своего собственного мастера новой мастер-веткой GitHub (или не выполнив много слияний).
Есть альтернативы git push --force для публичных репозиториев.
Ответ Джефроми (объединение правых изменений с оригинальным мастером) - один из них.
Можно также извлечь все файлы из другой ветки в master:
git checkout master
git checkout better_branch -- .
и затем передайте все изменения.
Чтобы добавить к ответу Джефроми, если вы не хотите помещать бессмысленное слияние в историю source
ветка, вы можете создать временную ветку для ours
объединить, затем выбросить
git checkout <source>
git checkout -b temp # temporary branch for merge
git merge -s ours <target> # create merge commit with contents of <source>
git checkout <target> # fast forward <target> to merge commit
git merge temp # ...
git branch -d temp # throw temporary branch away
Таким образом, коммит слияния будет существовать только в истории target
ветка.
В качестве альтернативы, если вы вообще не хотите создавать слияние, вы можете просто получить содержимое source
и использовать их для нового коммита на target
:
git checkout <source> # fill index with contents of <source>
git symbolic-ref HEAD <target> # tell git we're committing on <target>
git commit -m "Setting contents to <source>" # make an ordinary commit with the contents of <source>
Что касается меня, я хотел, чтобы мой разработчик вернулся к мастеру после того, как он был впереди.
Пока на разработке:
git checkout master
git pull
git checkout develop
git pull
git reset --hard origin/master
git push -f
Мой способ ведения дел заключается в следующем
#Backup branch
git checkout -b master_backup
git push origin master_backup
git checkout master
#Hard Reset master branch to the last common commit
git reset --hard e8c8597
#Merge
git merge develop
Если вы используете eGit в Eclipse:
- Щелкните правой кнопкой мыши на узле проекта.
- Выберите Team → затем Advanced → затем переименовать ветку
- Затем разверните папку удаленного отслеживания.
- Выберите ветку с неправильным именем, затем нажмите кнопку переименования, переименуйте ее в любое новое имя.
- Выберите нового мастера, затем переименуйте его в мастера.
Просто зайдите на сайт gitlab или github и найдите настройки.
Затем в настройках найдите репозиторий.
Там найдите ветку по умолчанию, разверните ее, и вы сможете получить возможность переименовать ее или изменить на другую ветку.
Я попробовал это в gitlab, и это сработало.
У меня не хватает кармы, чтобы комментировать.
Я знаю, что OP не хотел этого, но вы можете сделать это, если знаете, что в будущем у вас возникнет проблема, аналогичная OP.
Предположим, вы заранее знаете, что хотите создать ветку, в которой будут новые потрясающие функции, и вы также хотите, чтобы эта ветка стала главной в будущем, и в то же время не хотите терять текущую главную ветку (которая будет заблудитесь, если вы сначала сделаете для нее отдельную ветку и потрясающие функции, а затем объедините ее в master). Если это сбивает с толку, см. Приведенную ниже диаграмму «плохой» ситуации.
Чтобы решить эту проблему (т.е. остановить потерю скучности), выполните следующие действия. В основном,
- Создайте копию своего текущего мастера, выполнив
git branch boring
Замени скучное имя, которое хочешь сохранить - Теперь вы можете добавлять новые потрясающие функции в свою основную ветку и добавлять скучные функции в скучную ветку.
- Вы все еще можете обновлять скучную ветку и, возможно, использовать ее с намерением никогда не объединять ее в master. Вы не потеряете скучных функций.
- В вашей основной ветке будут потрясающие функции.
Следующие шаги выполняются в браузере Git на платформе Atlassian (сервер Bitbucket)
Делая {current-branch} какmaster
- Сделай ветку из
master
и назовите его "мастер-дубликат". - Сделайте ветку из {current-branch} и назовите ее "{current-branch} -copy".
- В настройках репозитория (Bitbucket) измените "Ветвь по умолчанию", указав "master-duplicate" (без этого шага вы не сможете удалить master - "На следующем шаге").
- Удалить "основную" ветку - я сделал этот шаг из дерева исходных текстов (вы можете сделать это из CLI или браузера Git)
- Переименуйте "{current-branch}" в "master" и отправьте в хранилище (это создаст новую "master" ветку, но "{current-branch}" будет существовать).
- В настройках репозитория измените "Ветвь по умолчанию", чтобы указать на "мастер".
Я удивлен, что здесь нет ответа. Это то, что я сделал.
- Сделал 2 копии репо в моей файловой системе в разных каталогах, одну с мастером и одну с веткой.
- Скопировал (вручную) все файлы из ветки на master
- Зафиксировал изменения в master.
Таким образом, существует одна фиксация со всеми включенными различиями, история коммитов сохраняется, и не требуется никаких жестких принудительных толчков.