Сделайте текущую ветку Git главной веткой - PullRequest
1484 голосов
/ 04 мая 2010

У меня есть хранилище в Git. Я сделал ветку, затем сделал некоторые изменения как в мастере, так и в ветке.

Затем, спустя десятки коммитов, я понял, что ветвь находится в гораздо лучшем состоянии, чем мастер, поэтому я хочу, чтобы ветвь «стала» мастером и не обращала внимания на изменения на мастере.

Я не могу объединить это, потому что я не хочу сохранять изменения в master. Что мне делать?

Extra : в этом случае «старый» мастер уже push подключен к другому хранилищу, такому как GitHub. Как это меняет вещи?

Ответы [ 13 ]

1930 голосов
/ 04 мая 2010

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

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
282 голосов
/ 24 июня 2015

Убедитесь, что все загружено в ваш удаленный репозиторий (GitHub):

git checkout master

Перезаписать "master" на "better_branch":

git reset --hard better_branch

Принудительная передача в ваш удаленный репозиторий:

git push -f origin master
68 голосов
/ 04 мая 2010

Редактировать: Вы не сказали, что продвинулись в публичном репо! Это делает мир разницы.

Есть два пути: «грязный» и «чистый». Предположим, что ваша ветвь называется 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
42 голосов
/ 04 мая 2010

Переименуйте ветку в master:

git branch -M branch_name master
20 голосов
/ 05 апреля 2015

Насколько я понимаю, вы можете ветвить текущую ветку в существующую ветку. По сути, это перезапишет 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
13 голосов
/ 04 мая 2010

Решения, приведенные здесь (переименование ветви в 'master'), не настаивают на последствиях для удаленного (GitHub) репо:

    -f
    --force

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

Если другие уже извлекли ваше хранилище, они не смогут извлечь эту новую историю мастер-процессов, не заменив своего собственного мастера новой ветвью GitHub (или не выполнив множество слияний).
Есть альтернативы git push --force для публичных репо .
Ответ Джефроми (объединение правых изменений с оригинальным мастером) - один из них.

11 голосов
/ 08 апреля 2016

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

Цель: сделать текущее состояние «ветви» «ведущим»

Работая над веткой, внесите изменения и отправьте их, чтобы убедиться в актуальности локальных и удаленных репозиториев:

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

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

9 голосов
/ 04 марта 2014

Можно также извлечь все файлы из другой ветки в master:

git checkout master
git checkout better_branch -- .

и затем передайте все изменения.

6 голосов
/ 04 февраля 2018

Я нашел ответ, который хотел в сообщении в блоге Замените основную ветку другой веткой в ​​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

По сути, это то же самое, что и Ответ Каскабеля . За исключением того, что в «опцию» он добавил ниже , его решение уже встроено в мой основной кодовый блок.

Так проще найти.

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

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

4 голосов
/ 16 марта 2017

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