2010-01-06 10 views
10

Tout à l'heure j'ai commis et poussé quelque chose (oui, mon erreur sur la poussée) que j'ai décidé que je devrais «revenir» ou «annuler». Donc, on m'a dit d'émettre git reset --soft HEAD^ de ma part, et je me suis dit que cela créerait en quelque sorte un commit de «retour» qui, une fois validé, ferait comme si le changement ne s'était jamais produit. Cela ne me dérange pas si l'histoire du changement est là du tout, c'est exactement ce que j'imaginais.Impossible de pousser après git reset --soft HEAD^

De toute façon, après avoir fait cela, j'ai commis à nouveau, et puis quand j'ai essayé de pousser j'ai eu l'erreur non-forward-forward. Maintenant, je sais que j'ai foiré quelque chose avec la réinitialisation, quelque chose dans le sens de mon arbre et de l'arbre d'origine sont "désordonnés" maintenant, mais je me demande comment résoudre ce problème. Maintenant, je veux juste revenir à l'heure avant que j'ai émis la réinitialisation, de sorte que je peux simplement manuellement revenir sur les modifications en les retirant manuellement puis en validant, à moins que quelqu'un d'autre puisse recommander la manière correcte de retourner un commit poussé, et Je ne veux pas dire que l'histoire doit disparaître du journal ou de quoi que ce soit.

Répondre

7

Si je comprends bien, vous pouvez correctement votre problème essayez ce qui suit:

(je suppose que c'est votre branche « maître » et vous poussent à « l'origine »)

Sync avec votre télécommande pour arriver au même état.

git remote update 
git checkout master 
git merge origin/master 

Maintenant nous revenions votre livraison

git revert HEAD (or where ever the commit you want to revert is now) 
git commit -av 

Sync avec votre télécommande

git push 
0

Vous vouliez utiliser git revert HEAD pour créer un nouveau commit qui annulerait la commettras à la HEAD. Au lieu de cela, vous venez de déplacer HEAD vers le commit avant le HEAD actuel.

+0

Merci, cela a du sens, même si cela aurait probablement été mieux comme un commentaire étant donné qu'il ne résout pas vraiment mon problème. Merci quand même. –

5

Maintenant, je veux juste revenir à l'heure avant délivré la remise à zéro

Si vous voulez seulement annuler la vous git reset --soft venez de faire, vous pouvez consulter l'ancien chef commettre id dans la reflogs

$ git reflog 
$ git reset --soft formerCommit 

Et vous pouvez préparer votre git revert

+0

Merci, c'est similaire à ce que quelqu'un d'IRC m'a dit de faire, mais c'est assez déroutant alors je vais aller avec la réponse de rnicholson à des fins de documentation. –

+1

Je ne connaissais pas git reflog. Très sympa. J'ai appris quelque chose de nouveau. C'est probablement une meilleure solution car elle condense les 3 premières étapes de ma réponse à une commande. – rnicholson

0

Bien que ma réponse est au-delà de ce que vous demandez, Je pense que c'est ce que vous avez l'intention de faire.

Vous avez utilisé git reset --soft HEAD^ pour annuler le commit que vous avez effectué. Cela renvoie la copie de travail à l'état avant votre engagement (depuis HEAD points à votre commit en cours, et HEAD^ points le précédent (en supposant qu'il n'y a qu'un seul parent).

Mais maintenant, quand vous git push vous dit quelque chose comme:

! [rejected]   <branch> -> <branch>e (non-fast-forward) 
error: failed to push some refs to 'ssh://<remote server>/<remote path>' 
hint: Updates were rejected because the tip of your current branch is behind 
hint: its remote counterpart. Integrate the remote changes (e.g. 
hint: 'git pull ...') before pushing again. 
hint: See the 'Note about fast-forwards' in 'git push --help' for details. 

Cela revient à dire que les commits ne sont pas alignées et il est là pour vous empêcher de faire une erreur Le message d'erreur est un peu trompeur et vous ne voulez pas faire ce qu'il suggère. (une traction pour synchroniser votre branche.) Vous ne pouvez pas savoir ne pas le faire à cause de vos intentions.

Vous pouvez simplement contourner ce avec un --force (ou -f) (*):

git push --force 

Vous devrez peut-être régler le nouveau amont:

git push --force --set-upstream origin <branch> 

Soyez conscient que cela aura conséquences si d'autres ont déjà tiré votre travail, car il y aura différents commits qui feront les mêmes changements (éventuellement). Voir https://www.kernel.org/pub/software/scm/git/docs/user-manual.html#problems-With-rewriting-history.

Pour éviter tout problème, ne jamais faire pousse à vos branches (pas une branche commune - par exemple la branche development les devs se fondent toutes leurs branches fonctionnelles dans) et assurez-vous d'avoir communication ouverte dans votre équipe.

Un développeur serait généralement utiliser ce modèle pour ce que j'appelle vendredi après-midi engage où vous souhaitez enregistrer votre travail avant le week-end en cas de défaillance matérielle (mais revenir à l'état pré-engager le lundi) .

*Friday* 

git add --all # To add all files whether they are tracked or not 
git commit -m "Friday afternoon commit" 
git --set-upstream push  # --set-upstream is for if the branch doesn't exist on the remote server 

*Monday* 

git reset --soft HEAD^ 
git push -f --set-upstream origin <branch> 

L'avantage de le faire de cette façon, par rapport à un git revert discuté dans une autre réponse, est d'éviter commits supplémentaires. La réinitialisation aura 2 commits et de cette façon n'en aura aucun (aucun supplémentaire). L'avantage de git reset est de ne PAS réécrire l'histoire, c'est donc beaucoup plus sûr, surtout si vous n'êtes pas sûr de ce que vous faites. (*) En règle générale, les référentiels sont configurés pour ne PAS vous laisser faire cela à maître - réparer sur une branche et créer une demande de traction à la place. Car si vous avez lu le lien ci-dessus, réécrire l'histoire sur le master aura des conséquences GRAVES (sauf si vous êtes la seule personne à cloner ce code).