Сделайте текущую ветку Git главной веткой

1412

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

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

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

Дополнительно: В этом случае "старый" мастер уже был push -ed в другой репозиторий, такой как GitHub. Как это может измениться?

  • 1
    Проверьте ответы на очень похожий вопрос stackoverflow.com/q/2862590/151641
  • 4
    Возникла такая же проблема, однако я просто удалил мастер и переименовал другую ветку в мастер: stackoverflow.com/a/14518201/189673
Показать ещё 2 комментария
Теги:

14 ответов

1869
Лучший ответ

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

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
  • 20
    Замечание о "стратегиях" слияния в git: --strategy=ours отличается от --strategy=recursive -Xours . Т.е. «наша» может быть стратегией сама по себе (результатом будет текущая ветка, не смотря ни на что) или передаваться в качестве опции «рекурсивной» стратегии (вносить изменения в другую ветку и автоматически отдавать предпочтение изменениям текущей ветви в случае конфликта ).
  • 0
    Если бы существовали ветки, основанные на "better_branch", над которыми вы хотели бы продолжить работу, вам нужно было бы сохранять "better_branch" до тех пор, пока они не были объединены с master, или вы могли бы удалить "better_branch"?
Показать ещё 23 комментария
190

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

git checkout master

Перезаписать "master" с помощью "better_branch":

git reset --hard better_branch

Вставьте push в удаленный репозиторий:

git push -f origin master
  • 49
    Это, вероятно, ответ, который ищут большинство людей. Все остальные ответы со слиянием стратегии BS не заменяют полностью ветку. Это сделало все так, как я хотел, просто переписать ветку и подтолкнуть ее вверх.
  • 14
    хотя это действительно то, что многие ищут, следует отметить, что любые другие локальные копии репо должны будут git reset --hard origin/master следующий раз, когда они захотят получить, иначе git попытается объединить изменения в свои (сейчас) расходятся местные. Опасности этого объясняются больше в этом ответе
Показать ещё 3 комментария
62

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

Есть два пути: "грязный" способ и "чистый" способ. Предположим, что ваша ветка называется 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
  • 1
    Спасибо. Еще один вопрос. Я подталкиваю это к github. Что там будет, если я это сделаю?
  • 2
    @Karel: Это создаст беспорядок для других пользователей; им придется сбросить своего хозяина на мастера github. Если вы хотите избежать неприятностей, взгляните на мой ответ.
Показать ещё 5 комментариев
42

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

git branch -M branch_name master
  • 10
    К сожалению, git не отслеживает переименования веток, поэтому, если вы уже перенесли репо на удаленный компьютер, а другие имеют локальные изменения в своей старой локальной ветке master, у них будут проблемы.
  • 0
    есть ли разница между этим и git checkout master&&git reset --hard better_branch ?
12

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

    -f
    --force

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

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

10

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

git branch -f master HEAD

Как только вы это сделаете, вы можете обычно нажимать свою локальную ветвь master, возможно, также требующую параметр силы:

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 on the remote
git reset --hard origin/master
  • 0
    Очень просто и отлично работает! Две простые и понятные команды git. Мой репозиторий git сохранен и теперь выглядит очень чисто. Спасибо!
6

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

Цель: Сделать текущее состояние "ветки" "мастером"

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

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

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

6

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

git checkout master
git checkout better_branch -- .

а затем зафиксировать все изменения.

3

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

Это по сути то же, что и ответ Каскабеля. За исключением того, что "вариант", который он добавил ниже своего решения, уже встроен в мой основной блок кода.

Легче найти этот путь.

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

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

3

Чтобы добавить к ответу Jefromi, если вы не хотите размещать бессмысленное слияние в истории ветки 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>
0

Мой способ делать вещи следующий

#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
0

Если вы используете eGit в Eclipse:

  • Щелкните правой кнопкой мыши узел проекта.
  • Выберите команду → затем Дополнительно → затем переименовать ветвь
  • Затем разверните папку удаленного отслеживания.
  • Выберите ветку с неправильным именем, затем нажмите кнопку переименования, переименуйте ее в любое новое имя.
  • Выберите нового мастера, затем переименуйте его в мастер.
  • 0
    Я сделал это, но не уверен, сработало ли это. На github ничего не изменилось, но на расширениях git я вижу, что ветка была переименована.
-1

Следующие шаги выполняются в браузере Git на базе Atlassian (сервер Bitbucket)

Создание {current-branch} в качестве master

  1. Сделайте ветку из master и назовите ее "master-duplicate".
  2. Сделайте ветку из {current-branch} и назовите ее "{current-branch} -copy".
  3. В настройках репозитория (Bitbucket) измените "Разделение по умолчанию" на "master-duplicate" (без этого шага вы не сможете удалить мастер - "В следующем шаге").
  4. Удалить ветку "master" - я сделал этот шаг из исходного дерева (вы можете сделать это из браузера CLI или Git)
  5. Переименуйте "{current-branch}" в "master" и нажмите на репозиторий (это создаст новую "ведущую" ветвь, все еще "{current-branch}" будет существовать).
  6. В настройках репозитория измените "Разделитель по умолчанию", чтобы указать "мастер".
-4

Использование:

get fetch && git checkout branch

Ещё вопросы

Сообщество Overcoder
Наверх
Меню