Question Faire de la branche Git actuelle une branche maîtresse


J'ai un référentiel dans Git. J'ai fait une branche, puis j'ai fait quelques changements à la fois au maître et à la branche.

Ensuite, des dizaines de commits plus tard, j'ai réalisé que la branche est dans un bien meilleur état que le master, donc je veux que la branche "devienne" le maître et ne tienne pas compte des changements sur le master.

Je ne peux pas le fusionner, parce que je ne veux pas garder les changements sur le maître. Que devrais-je faire?

Supplémentaire: Dans ce cas, le «vieux» maître a déjà été push-ed à un autre référentiel tel que GitHub. Comment cela change les choses?


1310
2018-05-04 05:30


origine


Réponses:


Le problème avec les deux autres réponses est que le nouveau maître n'a pas l'ancien maître comme ancêtre, donc quand vous le poussez, tout le monde sera foiré. C'est ce que vous voulez faire:

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

Si vous voulez que votre historique soit un peu plus clair, je vous recommande d'ajouter quelques informations au message de validation de fusion pour clarifier ce que vous avez fait. Changez la deuxième ligne pour:

git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message

1743
2018-05-04 06:00



Assurez-vous que tout est poussé dans votre dépôt distant (GitHub):

git checkout master

Ecraser "master" avec "better_branch":

git reset --hard better_branch

Forcer la poussée vers votre dépôt distant:

git push -f origin master

168
2018-06-24 20:25



Modifier: Vous n'avez pas dit que vous aviez poussé à un dépôt public! Cela fait un monde de différence.

Il y a deux façons, la manière "sale" et la manière "propre". Supposons que votre branche soit nommée new-master. C'est la manière propre:

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

Cela fera que les fichiers de configuration changent pour correspondre aux branches renommées.

Vous pouvez également le faire à la manière sale, ce qui ne mettra pas à jour les fichiers de configuration. C'est un peu ce qui se passe sous le capot de ce qui précède ...

mv -i .git/refs/new-master .git/refs/master
git checkout master

65
2018-05-04 05:37



Renommez la branche en master par:

git branch -M branch_name master

39
2018-05-04 05:37



Les solutions données ici (renommer la branche en 'master') n'insistent pas sur les conséquences pour le repo distant (GitHub):

    -F
    --Obliger

Habituellement, la commande refuse de mettre à jour une référence distante qui n'est pas un ancêtre de la référence locale utilisée pour l'écraser. Ce drapeau désactive le contrôle. Cela peut entraîner la perte de validations du référentiel distant; utilisez-le avec soin.

Si d'autres ont déjà retiré votre repo, ils ne pourront pas récupérer ce nouvel historique de master sans remplacer leur propre master par cette nouvelle branche master de GitHub (ou traiter beaucoup de fusions).
Il y a alternatives à un push git --force pour les repos publics.
La réponse de Jefromi (fusionner les bons changements vers le maître d'origine) en fait partie.


11
2018-05-04 05:57



D'après ce que je comprends, vous pouvez branchez la branche actuelle dans une branche existante. En substance, cela écrasera master avec tout ce que vous avez dans la branche actuelle:

git branch -f master HEAD

Une fois que vous avez fait cela, vous pouvez normalement pousser votre locale master branche, nécessitant éventuellement la Obliger paramètre ici aussi:

git push -f origin master

Pas de fusion, pas de longues commandes. Simplement branch et push- mais oui, cela réécrira l'histoire du master branche, donc si vous travaillez dans une équipe, vous devez savoir ce que vous faites.




Alternativement, j'ai trouvé que vous pouvez pousser n'importe quelle branche vers n'importe quelle branche distante, donc:

# 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

10
2018-04-04 22:44



On peut également extraire tous les fichiers de l'autre branche vers le master:

git checkout master
git checkout better_branch -- .

puis validez tous les changements.


6
2018-03-04 17:51



J'ai trouvé cette méthode simple pour travailler le mieux. Il ne réécrit pas l'historique et tous les enregistrements précédents de la branche seront ajoutés au maître. Rien n'est perdu et vous pouvez voir clairement ce qui s'est passé dans le journal de validation.

Objectif: Rendre l'état actuel de "branche" le "maître"

En travaillant sur une branche, validez et validez vos modifications pour vous assurer que vos référentiels locaux et distants sont à jour:

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

Après cela, votre maître sera l'état exact de votre dernière validation de branche et votre journal de validation principal affichera tous les check-ins de la branche.


5
2018-04-08 15:30



Pour ajouter à la réponse de Jefromi, si vous ne voulez pas placer une fusion sans signification dans l'histoire de source branche, vous pouvez créer une branche temporaire pour le ours fusionnez, puis jetez-le:

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

De cette façon, le commit de fusion ne sera disponible que dans l'histoire de target branche.

Sinon, si vous ne souhaitez pas créer de fusion, vous pouvez simplement récupérer le contenu de source et les utiliser pour un nouveau commit sur 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
2018-03-16 17:16