Comment puis-je annuler un commit?

127

J'ai 2 commits que je n'ai pas poussé:

$ git status
# On branch master
# Your branch is ahead of 'faves/master' by 2 commits.

Comment puis-je annuler mon premier (le plus ancien), tout en conservant le second?

 $ git log
commit 3368e1c5b8a47135a34169c885e8dd5ba01af5bb
...

commit baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e
...

D'ici:

http://friendfeed.com/harijay/742631ff/git-question-how-do-i-rollback-commit-just-want

Dois-je juste faire:

git reset --hard baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e

C'est?

n179911
la source
3
Cette question semble être hors sujet car il s'agit d'un outil de programmation. Il appartient à Stack Overflow.
Peter Mortensen
@PeterMortensen D'accord. Ceci est du ressort du superutilisateur
Kolob Canyon

Réponses:

95

Le moyen le plus sûr et probablement le plus propre consiste à procéder à une refonte interactive.

git rebase -i HEAD^^

Ou,

git rebase -i baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e^

À partir de là, vous pouvez écraser les commits, ce qui permet de regrouper un ou plusieurs commits dans le commit précédent. Pour supprimer complètement un commit de l'historique, supprimez la ligne de la liste.

Vous pouvez annuler un commit avec git revertmais cela va ajouter plus de messages de commit à l'historique, ce qui peut être indésirable. Utilisez le -nparamètre pour dire à Git de ne pas valider le retour immédiatement. Vous pouvez créer une base interactive de manière interactive et écraser ceux qui se trouvent jusqu'à un précédent engagement afin de garder les choses propres.

Si les deux commits que vous travaillez ici affectent le même fichier (s), vous pouvez voir un conflit de fusion.

La réinitialisation du référentiel avec git reset --harddoit être effectuée avec précaution, car elle ne peut pas être annulée.

La récriture de l'historique doit être faite avec soin.

jtimberman
la source
Comment puis-je supprimer un commit pendant 'git rebase'? Il n'y a que 3 commandes: pick, edit, squash. Il n'y a pas de suppression autant que je sache.
n179911
8
supprime entièrement la ligne de la liste et supprime cette commande
jtimberman
quand je voulais inverser le changement, je voulais ne laisser aucune trace de celui-ci. Si vous souhaitez également ne laisser aucune trace de votre retour, c’est la meilleure façon de le faire.
Phillip Whelan
"Le moyen le plus sûr et probablement le plus propre consiste à procéder à une refonte interactive" Peut-être pas si vous n'utilisez pas vim. J'ai eu de la chance et je me suis débrouillé pour sortir de ce pétrin. Toujours plus de votes parce que je devrais apprendre vim :-)
isimmons
Je suggère d'utiliser rebasele moins possible. Si vous travaillez avec d'autres, faites-le revert.
boldnik
52

Ceci si de http://nakkaya.com/2009/09/24/git-delete-last-commit/ et cela a fonctionné pour moi

Git Delete Last Commit

De temps en temps tard dans la nuit quand je manque de café, je commets des choses que je n'aurais pas dû. Ensuite, je passe les 10 à 15 prochaines minutes à chercher sur Google comment supprimer le dernier commit que j'ai fait. Donc, après la troisième fois, je voulais en faire un enregistrement pour pouvoir le consulter plus tard.

Si vous avez commis des junk mais pas poussé,

git reset --hard HEAD~1

HEAD ~ 1 est un raccourci pour le commit avant head. Sinon, vous pouvez vous référer au SHA-1 du hachage que vous souhaitez réinitialiser. Notez que lorsque vous utilisez --hard, toutes les modifications apportées aux fichiers suivis dans l’arbre de travail depuis la validation avant l’en-tête sont perdues.

Si vous ne voulez pas effacer le travail que vous avez fait, vous pouvez utiliser l' --softoption qui supprimera la validation mais laissera tous vos fichiers modifiés "Modifications à valider", comme le dirait le statut de git.

Maintenant, si vous avez déjà poussé et tiré quelqu'un qui est généralement mon cas, vous ne pouvez pas utiliser git reset. Vous pouvez cependant faire un git revert,

git revert HEAD

Cela créera un nouveau commit qui annule tout ce qui a été introduit par le commit accidentel.

iStryker
la source
2
Avec l'option --soft, c'est l'endroit idéal pour renommer un fichier et accidentellement "git commit -a" plutôt que d'utiliser "git add" en premier.
Aaron Harun
8

Nan. git-reset --hard vous ramènera dans l'histoire. Ce que vous recherchez, c'est git revert, ce qui annulera tout commit.

Peltier
la source
4
Eh bien, cela fonctionne, mais cela pollue également le journal. Si ces commits n'ont pas déjà été poussés / tirés, mieux vaut les nettoyer avec une rebase interactive. La possibilité de modifier l'historique est l'un des principaux avantages de git par rapport aux autres systèmes de contrôle de version.
knweiss
6

Je viens de faire ceci:

git rebase -i HEAD^^

Je l'ai bousillé alors j'ai fait

git rebase --abort

Puis il l'a fait à nouveau. Ensuite, j'ai dû pousser comme ceci:

git push origin master -f

Et il a détruit les commits plus récents que ceux auxquels je suis retourné. A bien fonctionné.

hamstar
la source
4

Non, git reset --hard baf8d5esupprimera le 3368e1ccommit et HEAD sera à la baf8d5esuite.

Si vous souhaitez conserver la 3368e1cvalidation et la supprimer, la bad8d5esolution la plus simple consiste à effectuer un " git rebase -i HEAD~2" (c.-à-d. Une rebase interactive des deux dernières validations). Cette commande lancera votre éditeur de message de validation et vous verrez une ligne pour chacun des deux derniers validés. Là, vous venez de supprimer la bad8d5eligne de validation et de sauvegarder. git va alors réécrire votre historique et le 2ème commit sera parti.

Il existe d' autres commandes utiles que vous pouvez utiliser dans l'éditeur de message de commit comme squash, edit, etc. rebasage Interactive est très puissant!

Ne faites pas cela si quelqu'un a déjà vu ces commits (pousser ou tirer de votre référentiel)!

knweiss
la source
1
git reset --hard {ref}

est le seul moyen d'annuler une validation s'il n'y a qu'une seule autre validation dans le référentiel (par exemple, une validation initiale et une autre). Les autres méthodes (retour, rebase) refusent de fonctionner, du moins à partir de la version 1.7.5.1.

Si vous suivez le git resetavec un, git gcgit supprimera complètement les anciennes données de validation du référentiel.

raclette
la source
1
git checkout <treeish> -- /path/to/dir

Cela ramènera le répertoire du "treeish" donné pour le / chemin / vers / dir

lokeshpahal
la source
0

Cela a fonctionné en modifiant manuellement les codes de hachage des derniers commits à partir des fichiers HEAD dans le dossier du référentiel:

"centralRepository\refs\heads\master"
"centralRepository\refs\heads\branch2"

Avant cela, je n'avais jamais réussi à pousser à l'origine des opérations UNMERGE que j'avais effectuées localement. Il n'arrêtait pas de dire qu'il "n'avait pas réussi à envoyer des références" au dépôt central.

Leandro M
la source