868 votes

Renommer la branche master pour les dépôts Git locaux et distants

J'ai la branche master qui suit la branche distante origin/master .

Je veux les renommer en master-old à la fois localement et sur le site distant. Est-ce possible ?

Pour les autres utilisateurs qui ont suivi origin/master (et qui ont toujours mis à jour leur master branche via git pull ), que se passerait-il si je renommais la branche distante ?
Est-ce que leur git pull fonctionnerait toujours ou bien une erreur se produirait, indiquant qu'il n'a pas pu trouver origin/master plus ?

Ensuite, plus loin, je veux créer une nouvelle master (à la fois localement et à distance). Encore une fois, après avoir fait cela, que se passe-t-il maintenant si les autres utilisateurs font git pull ?

Je suppose que tout cela entraînerait beaucoup d'ennuis. Existe-t-il un moyen propre d'obtenir ce que je veux ? Ou devrais-je simplement laisser master telle qu'elle est et créer une nouvelle branche master-new et y travailler plus tard ?

2 votes

La recette donnée dans la réponse acceptée s'applique à une branche de n'importe quel nom, mais les avertissements (comme indiqué) ne s'appliquent pas, en raison du rôle spécial (par défaut) de l'attribut maître dans Git.

3 votes

@kynan : Je crois que je ne comprends pas. Quels avertissements s'appliquent à master et ne s'appliquent pas aux autres branches ? Si c'est une branche nommée xy et que d'autres personnes ont suivi cette branche, en quoi cela serait-il différent ?

4 votes

L'inconvénient est que vous ne pouvez normalement pas supprimer le maître distant. Cela ne s'applique pas à la réponse d'Aristote, vous pouvez donc la marquer comme étant la réponse acceptée. Vous avez raison, tout git push -f affecte la capacité à pull à partir de n'importe quelle branche de suivi à distance.

640voto

bdonlan Points 90068

Ce qui se rapproche le plus d'un renommage, c'est la suppression, puis la recréation sur la télécommande. Par exemple :

git branch -m master master-old
git push remote :master         # Delete master
git push remote master-old      # Create master-old on remote

git checkout -b master some-ref # Create a new local master
git push remote master          # Create master on remote

Toutefois, cette méthode présente de nombreux inconvénients. Tout d'abord, aucun checkout existant ne sera informé du changement de nom - Git ne fait pas de distinction entre les deux. pas tente de suivre les renommages de branches. Si le nouveau master n'existe pas encore, git pull se trompera. Si le nouveau master a été créé. le pull va tenter de fusionner master y master-old . C'est donc généralement une mauvaise idée, sauf si vous avez la coopération de toutes les personnes qui ont extrait le dépôt précédemment.

Note : Les versions plus récentes de Git ne vous permettront pas de supprimer la branche master à distance par défaut. Vous pouvez passer outre en définissant l'option receive.denyDeleteCurrent de la valeur de la configuration pour warn o ignore sur le à distance dépôt. Sinon, si vous êtes prêt à créer un nouveau master tout de suite, sautez la section git push remote :master étape, et passer --force au git push remote master étape. Notez que si vous n'êtes pas en mesure de modifier la configuration de la branche distante, vous ne serez pas en mesure de supprimer complètement la branche maître !

Cette mise en garde ne s'applique qu'à la branche en cours (généralement la branche master ) ; toute autre branche peut être supprimée et recréée comme ci-dessus.

3 votes

Les branches sont juste une paire (nom, hash) - rien de plus, rien de moins. Il y a le reflog sur les branches, mais cela n'est jamais exposé aux clients distants.

141 votes

Je créerais master-old sur remote avant de supprimer master sur remote. Je suis juste paranoïaque.

0 votes

Pas de résultat à la deuxième commande : "remote : error : Par défaut, la suppression de la branche courante est refusée, parce que le prochain remote : error : 'git clone' ne donnera pas lieu à l'extraction d'un fichier, ce qui entraînera une confusion. remote : error : remote : error : Vous pouvez définir la variable de configuration 'receive.denyDeleteCurrent' t remote : error : 'warn' ou 'ignore' dans le référentiel distant pour autoriser la suppression de la remote : error : branche courante, avec ou sans message d'avertissement. remote : error : remote : error : Pour étouffer ce message, vous pouvez lui attribuer la valeur 'refuse'. remote : error : refusant de supprimer la branche courante : refs/heads/master"

267voto

Aristotle Pagaltzis Points 43253

En supposant que vous êtes actuellement sur master :

git push origin master:master-old        # 1
git branch master-old origin/master-old  # 2
git reset --hard $new_master_commit      # 3
git push -f origin                       # 4
  1. Faites d'abord un master-old dans le origin basé sur le référentiel master dans le référentiel local.
  2. Créez une nouvelle branche locale pour cette nouvelle origin/master-old (qui sera automatiquement configurée comme une branche de suivi).
  3. Maintenant, dirigez votre master vers le commit vers lequel vous voulez qu'il pointe.
  4. Enfin, le changement de force master dans le origin pour refléter votre nouveau dépôt local master .

(Si vous le faites d'une autre manière, vous avez besoin d'au moins une étape supplémentaire pour garantir que master-old est correctement configuré pour suivre origin/master-old . Aucune des autres solutions affichées au moment de la rédaction de cet article n'inclut cela).

15 votes

C'est une meilleure réponse que "la réponse", je suis d'accord, mais pour les personnes qui sont venues ici pour simplement renommer une branche (pas explicitement master), la 3ème étape n'a pas beaucoup de sens.

0 votes

Cela ne change absolument rien à la réponse que vous soyez sur master ou une autre branche. La question était pourtant mal titrée, elle porte sur une tâche plus complexe que juste renommer une branche.

3 votes

Cette solution s'est avérée être celle qui a fonctionné pour moi. J'essayais de remplacer master par une autre branche. J'ai fait un git log -1 origin/what_i_want_as_new_master pour obtenir le $new_master_commit pour l'étape 3. Après le push (étape 4), d'autres développeurs tiraient et obtenaient des messages "votre branche est en avance sur master de 295 commits". Pour résoudre ce problème, j'ai envoyé un courriel leur indiquant de lancer chacun : git pull ; git checkout some_random_branch ; git branch -D master ; git pull ; git checkout master ; En gros, ils doivent supprimer leur master local et tirer la nouvelle version, sinon ils sont au mauvais endroit localement.

175voto

Excalibur Points 855

Avec Git v1.7, je pense que cela a légèrement changé. Il est maintenant très facile de mettre à jour la référence de suivi de votre branche locale vers le nouveau fichier distant.

git branch -m old_branch new_branch         # Rename branch locally    
git push origin :old_branch                 # Delete the old branch    
git push --set-upstream origin new_branch   # Push the new branch, set local branch to track the new remote

14 votes

Une alternative à --set-upstream est la suivante : Une fois que votre branche a été renommée localement et supprimée sur l'origine, il suffit de faire : git push -u --all

1 votes

Que se passe-t-il pour le reste de l'équipe une fois que c'est fait ? Que doivent faire les autres membres de l'équipe pour passer à la nouvelle branche ?

6 votes

Cela ne fonctionnera pas avec la branche master, car git ne vous permettra pas de supprimer le master distant.

38voto

Treken Points 261
git checkout -b new-branch-name
git push remote-name new-branch-name :old-branch-name

Vous devrez peut-être passer manuellement à new-branch-name avant de supprimer old-branch-name

0 votes

Est-ce qu'une partie de cette solution supprime l'ancien nom de la branche locale, ou est-ce un exercice séparé ?

4 votes

Je pense qu'à la fin il faut courir git branch -d old-branch-name pour supprimer l'ancienne branche locale.

0 votes

Vous pouvez pousser les changements par une seule commande : git push remote-name new-branch-name :old-branch-name .

12voto

Jefromi Points 127932

Je présume que vous demandez toujours la même chose que dans votre question précédente . C'est-à-dire que le maître-nouveau ne contiendra pas le maître-ancien dans son histoire.* Si vous appelez le maître-nouveau "maître", vous aurez effectivement réécrit l'histoire. Cela n'a pas d'importance comment on arrive à un état dans lequel le maître n'est pas un descendant d'une position précédente de maître, simplement qu'il est dans cet état.

Les autres utilisateurs qui tentent d'effectuer des extractions alors que le master n'existe pas verront simplement leurs extractions échouer (pas de tel ref sur le dépôt distant), et une fois qu'il existe à nouveau à un nouvel endroit, leurs extractions devront tenter de fusionner leur master avec le nouveau master distant, tout comme si vous aviez fusionné master-old et master-new dans votre dépôt. Étant donné ce que vous essayez de faire ici, la fusion aurait des conflits. (S'ils étaient résolus, et que le résultat était repoussé dans le référentiel, vous seriez dans un état encore pire - les deux versions de l'historique là).

Pour répondre simplement à votre question : vous devez accepter que parfois il y aura des erreurs dans votre histoire. Ce n'est pas grave. Cela arrive à tout le monde. Il y a des commits réversibles dans le dépôt git.git. L'important est qu'une fois que nous publions l'historique, c'est quelque chose en quoi tout le monde peut avoir confiance.

*Si c'était le cas, cela reviendrait à pousser des changements sur master, puis à créer une nouvelle branche à l'endroit où elle se trouvait auparavant. Pas de problème.

0 votes

Oui, c'est le même problème, j'ai juste une idée pour le résoudre. Mais même si je ne ferais pas ce renommage de branche, je me demandais si c'était possible. Je pensais que des références telles que "master" ne sont que des références à des commits spécifiques. Je ne veux vraiment pas changer l'histoire. Je pensais simplement faire pointer la référence "master" vers une autre tête. Cela signifie également que je ne pourrai plus jamais utiliser un nom de branche si je l'ai déjà utilisé auparavant ?

0 votes

En effet, les branches sont des refs - des pointeurs vers les commits. Le fait est que nous nous attendons à ce que la tête d'une branche évolue d'une manière particulière (à savoir, toujours en avance rapide). Du point de vue de quelqu'un d'autre, déplacer une branche dans votre repo public revient à réécrire l'histoire de la branche. Elle ne pointe plus vers un commit contenant tout ce qu'elle contenait auparavant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X