Вопрос: Сделать текущую ветвь Git главной ветвью


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

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

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

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


1294


источник


Ответы:


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

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

1719



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

git checkout master

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

git reset --hard better_branch

Принудительное нажатие на удаленный репозиторий:

git push -f origin master

158



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

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

64



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

git branch -M branch_name master

39



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

-f
    --force 

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

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


11



Насколько я понимаю, вы можете разветвить текущую ветвь на существующую ветку. По сути, это будет перезаписано 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's on the remote
git reset --hard origin/master

8



One can also checkout all files from the other branch into master:

git checkout master
git checkout better_branch -- .

and then commit all changes.


6



I found this simple method to work the best. It does not rewrite history and all previous check-ins of branch will be appended to the master. Nothing is lost, and you can clearly see what transpired in the commit log.

Objective: Make current state of "branch" the "master"

Working on a branch, commit and push your changes to make sure your local and remote repositories are up to date:

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

After this, your master will be the exact state of your last commit of branch and your master commit log will show all check-ins of the branch.


4



To add to Jefromi's answer, if you don't want to place a meaningless merge in the history of the source branch, you can create a temporary branch for the ours merge, then throw it away:

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

That way the merge commit will only exist in the history of the target branch.

Alternatively, if you don't want to create a merge at all, you can simply grab the contents of source and use them for a new commit on 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>

3



I found the answer I wanted on this blog post Replace the master branch with another branch in 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

It's essentially the same as Cascabel's answer above.
Except that the "option" he added below his solution, is already embedded my main code block.

It's easier to find this way.

I'm adding this as a new answer, because if I need this solution later, I want to have all the code I am going to use in one code block.

Otherwise, I may copy-paste, then read details below to see the line that I should have changed - after I already executed it.


2