Supprimer le dernier commit dans bitbucket

103

J'ai fait une erreur et je ne sais pas comment supprimer mon dernier push dans le référentiel. Je tire les dernières mises à jour de l'application mais il y a des conflits et je la pousse vers le référentiel.

Comment supprimer mon dernier commit? Ou comment y remédier?

Catherine
la source

Réponses:

102

En premier lieu, si vous travaillez avec d'autres personnes sur le même référentiel de code, vous ne devez pas supprimer un commit car lorsque vous forcez la mise à jour sur le référentiel, cela laissera les référentiels locaux de vos collègues dans un état illégal (par exemple s'ils faites des commits après celui que vous avez supprimé, ces commits seront invalides car ils étaient basés sur un commit désormais inexistant).

Cela dit, ce que vous pouvez faire est d' annuler le commit. Cette procédure se fait différemment (différentes commandes) selon le CVS que vous utilisez:

Sur git :

git revert <commit>

Sur mercurial :

hg backout <REV>

EDIT: L'opération de retour crée un nouveau commit qui fait le contraire du commit rétabli (par exemple, si le commit d'origine a ajouté une ligne, le commit de retour supprime cette ligne), supprimant efficacement les modifications du commit indésirable sans réécrire l'historique du référentiel.

asermax
la source
Merci pour l'information. Et je connais la conséquence si je supprime le commit, je ne sais tout simplement pas comment annuler mon action car c'est la première fois que j'ai une erreur. J'ai besoin d'annuler mon commit car le système est déjà en ligne. Nous ne sommes que deux à travailler avec ce référentiel.
catherine
git backout <REV>? Ou hg backout <REV>:?
Armando Pérez Marqués
Mais que se passe-t-il si les commits ajoutés après celui à annuler avaient apporté des modifications sur la ligne en cours de suppression?
rahs
@RahulSaha puisque ce que vous faites est essentiellement d'essayer de fusionner un commit dans la branche, je suis presque sûr que cela vous donnera un conflit de fusion que vous allez devoir résoudre.
asermax
98

Si vous ne travaillez pas avec les autres (ou êtes heureux de leur causer des ennuis importants) , il est possible de supprimer les commits des branches de bitbucket.

Si vous essayez de changer une branche non principale:

git reset HEAD^               # remove the last commit from the branch history
git push origin :branch_name  # delete the branch from bitbucket
git push origin branch_name   # push the branch back up again, without the last commit

si vous essayez de changer la branche principale

Dans git en général, la branche master n'est pas spéciale - c'est juste une convention. Cependant, bitbucket et github et les sites similaires nécessitent généralement qu'il y ait une branche principale (probablement parce que c'est plus facile que d'écrire plus de code pour gérer l'événement qu'un référentiel n'a pas de branches - pas sûr). Vous devez donc créer une nouvelle branche et en faire la branche principale:

# on master:
git checkout -b master_temp  
git reset HEAD^              # undo the bad commit on master_temp
git push origin master_temp  # push the new master to Bitbucket

Sur Bitbucket, allez dans les paramètres du référentiel, et changez la «Branche principale» en master_temp(sur Github, changez la «Branche par défaut»).

git push origin :master     # delete the original master branch from Bitbucket
git checkout master
git reset master_temp       # reset master to master_temp (removing the bad commit)
git push origin master      # re-upload master to bitbucket

Maintenant, allez sur Bitbucket et vous devriez voir l'historique que vous voulez. Vous pouvez maintenant accéder à la page des paramètres et redéfinir la branche principale en master.

Ce processus fonctionnera également avec tous les autres changements d'historique (par exemple git filter-branch). Vous devez simplement vous assurer de réinitialiser les validations appropriées, avant que le nouvel historique ne se sépare de l'ancien.

edit : apparemment, vous n'avez pas besoin d'aller à tous ces tracas sur github, car vous pouvez forcer une branche de réinitialisation .

Gérer les collaborateurs ennuyés

La prochaine fois que quelqu'un essaiera d'extraire de votre référentiel (s'il a déjà tiré le mauvais commit), l'extraction échouera. Ils devront réinitialiser manuellement un commit avant l'historique modifié, puis tirer à nouveau.

git reset HEAD^
git pull

S'ils ont retiré le mauvais commit et se sont engagés dessus , alors ils devront réinitialiser, puis git cherry-pickles bons commits qu'ils veulent créer, recréant efficacement la branche entière sans le mauvais commit.

S'ils n'ont jamais tiré le mauvais commit, alors tout ce processus ne les affectera pas et ils peuvent tirer normalement.

rien101
la source
1
Pour ceux qui sont plus à l'aise avec l'utilisation de SourceTree: 1) Pour changer de branche principale dans l'interface utilisateur Web de BitBucket, consultez les paramètres du référentiel. 2) Pour supprimer une branche dans l'interface utilisateur Web, consultez la page Branches. 3) Réinitialisez le repo local comme indiqué ci-dessus. 4) Poussez vos modifications locales pour recréer ces branches.
Richard Le Mesurier
2
En tant que personne qui a accidentellement poussé un secret, j'ai beaucoup apprécié la rigueur de cette réponse. Merci!
Couple
48

vous pouvez réinitialiser pour HEAD^forcer le pousser.

git reset HEAD^
git push -u origin master --force

Il supprimera votre dernier commit et reflétera sur bitbucket comme commit supprimé mais restera toujours sur leur serveur.

Shubanker
la source
Github l'autorisera, mais au moment d'écrire ces lignes, Bitbucket n'autorise pas les poussées forcées.
JamesQMurphy
4
en fait, bitbucket prend en charge les poussées forcées, mais au lieu de supprimer complètement les commits non suivis, il les marque comme supprimés.
Shubanker
La méthode recommandée à partir de bitbucket est d'utiliser revert. Mais je pense que dans mon cas, c'est plus approprié. Puisque je suis le seul à l'utiliser, et que je me sens plus propre que d'utiliser revert. Merci.
nafsaka
1
Oui, cela fonctionne toujours sur Bitbucket. Vous venez de me faire gagner beaucoup de temps! J'ai fait un commit / push de mon Eclipse et je me suis mélangé à un autre projet que j'avais. En partie à cause d'une mauvaise pratique de ma part en utilisant à la fois la ligne de commande et l'éclipse intégrée pour travailler sur git.
DarkCygnus
brillant, ou plus simple: réinitialisez la branche actuelle sur ce commit, puis utilisez cette force push vers le serveur pour résoudre mon problème
Anthony Kal
3

J'ai eu des problèmes avec git revert dans le passé (principalement parce que je ne suis pas tout à fait sûr de son fonctionnement.) J'ai eu du mal à revenir en arrière à cause de problèmes de fusion.

Ma solution simple est la suivante.

Étape 1.

 git clone <your repos URL> .

votre projet dans un autre dossier, puis:

Étape 2.

git reset --hard <the commit you wanna go to>

puis Étape 3.

dans votre dernier (et principal) répertoire de projet (celui qui a le dernier commit problématique) collez les fichiers de l'étape 2

Étape 4.

git commit -m "Fixing the previous messy commit" 

Étape 5.

Prendre plaisir

SudoPlz
la source
1
Couper et coller est vraiment compliqué. De plus, cela ne résoudrait pas le problème de la question.
Daniel Lee
1
git revertest simple: il crée un nouveau commit qui fait l'inverse des changements dans un commit précédent (ou plusieurs commits). Il ne supprime pas les commits, donc ce n'est pas pertinent pour cette question. De plus, l'étape de clonage n'est pas vraiment nécessaire.
naught101
1
Git revert est le mécanisme égal comme ci-dessus.
nafsaka
3

Voici une approche simple en 4 étapes maximum:

0 - Informez l'équipe que vous allez réparer le référentiel

Connectez-vous avec l'équipe et informez-les des changements à venir.

1 - Supprimer le dernier commit

En supposant que votre branche cible est master:

$ git checkout master              # move to the target branch
$ git reset --hard HEAD^           # remove the last commit
$ git push -f                      # push to fix the remote

À ce stade, vous avez terminé si vous travaillez seul.

2 - Corrigez les dépôts locaux de votre coéquipier

Chez vos coéquipiers:

$ git checkout master              # move to the target branch
$ git fetch                        # update the local references but do not merge  
$ git reset --hard origin/master   # match the newly fetched remote state

Si votre coéquipier n'a eu aucun nouveau commit, vous avez terminé à ce stade et vous devriez être synchronisé.

3 - Ramener les commits perdus

Supposons qu'un coéquipier ait un nouveau commit non publié qui a été perdu dans ce processus.

$ git reflog                       # find the new commit hash
$ git cherry-pick <commit_hash>

Faites cela pour autant de commits que nécessaire.

J'ai utilisé avec succès cette approche à plusieurs reprises. Il faut un effort d'équipe pour s'assurer que tout est synchronisé.

rbento
la source
2

Comme d'autres l'ont dit, vous souhaitez généralement utiliser hg backoutou git revert. Cependant, parfois, vous voulez vraiment vous débarrasser d'un commit.

Tout d'abord, vous voudrez accéder aux paramètres de votre référentiel. Cliquez sur le Strip commitslien.

Strip commits link dans les paramètres de bitbucket

Entrez l'ID de l'ensemble de modifications pour l'ensemble de modifications que vous souhaitez détruire, puis cliquez sur Preview strip. Cela vous permettra de voir le type de dommage que vous êtes sur le point de faire avant de le faire. Ensuite, cliquez simplement Confirmet votre commit n'est plus de l'histoire. Assurez-vous de dire à tous vos collaborateurs ce que vous avez fait, afin qu'ils ne repoussent pas accidentellement le commit incriminé.

nmichaels
la source
De quelle version s'agit-il et quelles autorisations sont requises? Il semble différent sur la v6.4.3 que je regarde, et cet élément n'est pas là. Je suis administrateur du référentiel.
Raphael
1

Une fois les modifications validées, il ne pourra plus être supprimé. car la nature fondamentale de commit n'est pas de supprimer.

Chose que vous pouvez faire (méthode simple et sûre),

Rebase interactif:

1) git rebase -i HEAD~2 # affichera vos 2 derniers commits

2) Votre commit sera répertorié comme, Récent apparaîtra en bas de la page LILO (dernier dans Last Out)

entrez la description de l'image ici

Supprimer entièrement la dernière ligne de validation

3) enregistrez-le par ctrl+XouESC:wq

maintenant votre branche sera mise à jour sans votre dernier commit.

Mohideen bin Mohammed
la source
1

Vous pouvez également écrire la commande pour Bitbucket comme mentionné par Dustin :

git push -f origin HEAD^:master

Remarque: au lieu de master, vous pouvez utiliser n'importe quelle branche. Et il supprime juste pousser sur Bitbucket.

Pour supprimer le dernier commit localement dans git, utilisez:

git reset --hard HEAD~1
invzbl3
la source
0

A présent, cloud bitbucket (je ne sais pas quelle version) permet de revenir sur un commit du système de fichiers comme suit (je ne vois pas comment revenir de l'interface Bitbucket dans le navigateur Chrome).

-sauvegardez l'intégralité de votre répertoire pour sécuriser les modifications que vous avez commises par inadvertance

-sélectionner le répertoire extrait

-bouton droit de la souris: tortoise git menu

-repo-browser (l'option de menu 'revert' annule uniquement les modifications non validées)

-appuyez sur le bouton HEAD

-sélectionnez la ligne supérieure (le dernier commit)

-bouton droit de la souris: annuler le changement par ce commit

-après avoir annulé les modifications sur le système de fichiers, appuyez sur commit

-ce met à jour GIT avec un message 'Revert (votre message précédent). Cela revient à commettre untel

-sélectionnez 'commit and push'.

Smriti
la source