Vous voulez changer mon maître en un commit plus ancien, comment puis-je faire cela?

92

Je veux revenir à un commit précédent, puis publier ce code, puis revenir au dernier commit.

c'est-à-dire que mon maître pointe vers une version de commit plus ancienne juste pour que je puisse publier cette version, alors je veux revenir au dernier commit que j'étais au départ.

Comment puis-je faire ceci?

Blankman
la source

Réponses:

100

Si vous voulez faire cela et rétablir le maître au commit précédent:

git checkout master~1            # Checkout previous commit on master
git checkout -b new_master       # Create branch for new master
git branch -D master             # Delete old master
git branch -mv new_master master # Make new_master master

Alternativement:

git reset --hard master~1        # Reset current branch to one commit ago on master
Tyler Brock
la source
1
Donc, un an plus tard, je regarde cela et je pense que c'est une manière terrible de le faire. Au moins, c'est un peu facile à comprendre.
Tyler Brock
1
oui c'est pourquoi j'ai voté pour, facile à comprendre, peut-être auriez-vous dû présenter un lien vers un meilleur moyen?
Andrew Atkinson
1
J'ai dû faire de même avec SourceTree. Le processus est similaire. 1) créez une nouvelle branche pour l'état actuel du maître, vous ne perdrez donc rien. 2) supprimer le maître 3) créer une nouvelle branche principale, en sélectionnant le commit souhaité
Danilo Gomes
Qu'arrive-t-il au commit que nous avons "supprimé" du maître après cela?
Arthur Colombini Gusmão
1
Cela doit être évité si vous avez un dépôt distant. Cela provoque des erreurs si vous le faites, car l'adresse du premier maître diffère de celle du nouveau maître que vous avez créé récemment.
MAChitgarha
60

Votre question n'est pas claire. Je pense que ce que vous demandez, c'est ceci:

git push -f origin $old_commit_id:master

Qu'est-ce que cela va faire? Cela poussera le $old_commit_idcommit à devenir originle nouveau responsable de originla masterbranche de.

Si c'est ce que vous vouliez, vous n'avez pas du tout besoin de toucher votre mastersuccursale locale .

Aristote Pagaltzis
la source
Cela a causé un master (non-fast-forward)échec pour moi. La solution @jtdubs a fonctionné.
Bobby Norton
3
Passez simplement -fpour le forcer - bien que le dépôt distant puisse être configuré pour interdire cela. J'ai mis à jour la réponse.
Aristote Pagaltzis
ne fonctionne pas pour moi, mais la réponse acceptée le fait
MobileMon
Vous n'avez pas dit exactement ce que vous vouliez ou pourquoi cela n'a pas fonctionné, donc je ne peux pas vous dire pourquoi cela n'a pas fonctionné et comment cela aurait pu être fait (si cela avait pu).
Aristotle Pagaltzis
Vous semblez perdre l'histoire passée à distance avec cette approche, c'était bien pour moi. Juste en l'appelant.
Shawn
43

utilisation git reset --hard <old commit number>

cela réinitialisera HEAD à cet ancien commit.

en outre, vous devez également utiliser git push -f originpour modifier le référentiel distant.

KawaiKx
la source
34

Si vous souhaitez éviter les pressions forcées, voici comment rétablir votre dépôt à un commit plus ancien et conserver tout le travail intervenant:

git checkout 307a5cd        # check out the commit that you want to reset to 
git checkout -b fixy        # create a branch named fixy to do the work
git merge -s ours master    # merge master's history without changing any files
git checkout master         # switch back to master
git merge fixy              # and merge in the fixed branch
git push                    # done, no need to force push!

Terminé! Remplacez 307a5cd par le commit que vous voulez dans votre dépôt.

(Je sais que les deux premières lignes peuvent être combinées, mais je pense que cela rend moins clair ce qui se passe)

Le voici graphiquement:

c1 -- c2 -- c3 -- c4 -- c2' -- c5 ...
        \              /
         '------------'

Vous supprimez effectivement c3 et c4 et redéfinissez votre projet sur c2. Cependant, c3 et c4 sont toujours disponibles dans l'historique de votre projet si vous souhaitez les revoir.

Bronson
la source
1
Cela a fonctionné sans accroc! Si vous êtes descendu jusqu'ici et que vous lisez ceci, cela semble être le moyen le plus propre de ramener le maître à un commit plus profond.
ddisqq le
Je ne trouve pas les mots pour expliquer à quel point je vous aime pour cela, je suis reconnaissant au-delà des mots d'avoir réussi à réparer quelque chose qui m'a mis sur écoute pendant 6h maintenant et m'a causé tant de maux de tête. Merci Monsieur!!!!!!!
Kostas Tsakalidis
9

En supposant un graphe de validation comme ceci:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                              (master)

Vous souhaitez d'abord effectuer le paiement masteret créer une branche qui pointe vers où masterse trouve actuellement:

git checkout master
git branch pointer master

Devrait ressembler à ceci maintenant:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                       (HEAD, master, pointer)

Maintenant que vous êtes déjà sur master, nous allons dire à la masterbranche de reculer d'un commit:

git reset master~1

Maintenant, masterdevrait être reculé d'un espace, mais la pointerbranche est toujours sur le commit le plus récent:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|           (HEAD, master)    (pointer)

À ce stade, vous pouvez pousser mastervers une télécommande, ou n'importe où, puis la fusionner en avance rapide vers la pointerbranche. Vous pouvez tuer la pointerbranche à ce stade:

git push origin master
git merge --ff-only pointer
git branch -D pointer

Finale:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|         [ origin/master ]    (HEAD, master)
C0M37
la source
1
Si l'origine / maître est à C, git push origin masteréchouera avec la pointe de votre branche actuelle est derrière son homologue distant . Vous devez également passer un indicateur -f.
sassospicco le
8

Vous pouvez simplement git checkout <commit-id>, faire ce que vous devez faire, puis git checkout masterrevenir au nouveau code.

Si vous avez réellement besoin de modifier l'ancien code pour le publier, vous devriez probablement:

git checkout -b my_release <commit-id>
... prepare code for release ...
... release code ...
git checkout master
git merge my_release

De plus, je ne saurais trop recommander git flow . Cela rend tout cela assez facile.

jtdubs
la source
1

Pour passer à une version précédente:

git checkout <version hash>

faites votre travail ici et engagez-vous avec

git commit --amend

Pour revenir au master :

git checkout master

Pablo Fernandez
la source
1
Cela ne fonctionnera pas. git reset --harda pointé sa branche principale vers l'ancien commit, donc git checkout masterne fera rien.
jtdubs
C'est vrai, merci pour la correction. +1 à vous, supprimerait ma réponse aussi mais je pense que l' commit --amendétape est assez utile
Pablo Fernandez
Quoi --amend?
Shafizadeh