web-dev-qa-db-fra.com

Puis-je supprimer un commit git mais conserver les modifications

Dans l'une de mes branches de développement, j'ai apporté des modifications à ma base de code. Avant de pouvoir compléter les fonctionnalités sur lesquelles je travaillais, je devais changer de branche pour maîtriser certaines fonctionnalités. Mais l'utilisation d'un "maître de caisse git" a préservé les modifications que j'ai également apportées à ma branche de développement, cassant ainsi certaines des fonctionnalités de maître. Donc, ce que j'ai fait, c'est de valider les modifications sur ma branche de développement avec un message de validation "validation temporaire", puis de commander le maître de la démonstration.

Maintenant que la démo est terminée et que je suis de retour au travail dans ma branche de développement, je souhaite supprimer le "commit temporaire" que j'ai effectué tout en préservant les modifications apportées. Est-ce possible?

842
tanookiben

C'est aussi simple que cela:

git reset HEAD^

git reset sans --hard ou --soft déplace votre HEAD vers le commit spécifié, sans modifier aucun fichier. HEAD^ fait référence au (premier) commit de votre commit actuel, qui dans votre cas est le commit avant le temporaire.

Notez qu’une autre option consiste à poursuivre normalement, puis à exécuter le prochain point de validation:

git commit --amend [-m … etc]

qui à la place edit le dernier commit, ayant le même effet que ci-dessus.

Notez que ceci (comme avec presque toutes les réponses git) peut causer des problèmes si vous avez déjà poussé le mauvais commit vers un endroit où quelqu'un d'autre pourrait l'avoir tiré. Essayez d'éviter cela

1310
Gareth

Il y a deux façons de gérer cela. Ce qui est plus facile dépend de votre situation

Réinitialiser

Si le commit dont vous voulez vous débarrasser était le dernier, et que vous n'avez effectué aucun travail supplémentaire, vous pouvez simplement utiliser git-reset

git reset HEAD^

Ramène votre branche au commit juste avant votre HEAD actuelle. Cependant, cela ne change pas réellement les fichiers de votre arbre de travail. En conséquence, les modifications qui se trouvaient dans ce commit apparaissent comme modifiées - c'est comme une commande 'uncommit'. En fait, j'ai un alias pour faire cela.

git config --global alias.uncommit 'reset HEAD^'

Ensuite, vous pouvez simplement utiliser git uncommit à l'avenir pour sauvegarder un commit.

écrasement

Réduire un commit signifie combiner deux commits ou plus en un. Je le fais assez souvent. Dans votre cas, une fonctionnalité semi-terminée est validée, puis vous la finissez et vous engagez à nouveau avec le message de validation permanent approprié.

git rebase -i <ref>

Je dis ci-dessus parce que je veux préciser que cela pourrait être un nombre quelconque de commits de retour. Exécutez git log et trouvez le commit dont vous souhaitez vous débarrasser, copiez son SHA1 et utilisez-le à la place de <ref>. Git vous emmènera en mode rebase interactif. Il montrera tous les commits entre votre état actuel et ce que vous avez mis à la place de <ref>. Donc, si <ref> vaut 10 commits, il vous montrera tous les 10 commits.

Devant chaque commit, il aura la Parole pick. Recherchez le commit dont vous souhaitez vous débarrasser et remplacez-le de pick par fixup ou squash. Utiliser fixup supprime simplement le message validé et les modifications apportées à son prédécesseur immédiat dans la liste. Le mot clé squash fait la même chose, mais vous permet de modifier le message de validation de la nouvelle validation combinée.

Notez que les commits seront ré-validés dans l'ordre dans lequel ils apparaissent dans la liste lorsque vous quittez l'éditeur. Ainsi, si vous effectuez une validation temporaire, si d'autres travaux sont effectués sur la même branche et si la fonctionnalité est complétée dans une validation ultérieure, utiliser rebase vous permettra de trier à nouveau les validations et de les écraser.

ATTENTION:

La modification de la base modifie l’historique - NE FAITES PAS cela pour tous les commits que vous avez déjà partagés avec d’autres développeurs.

Stashing

Pour éviter ce problème à l'avenir, envisagez d'utiliser git stash pour stocker temporairement les travaux non validés.

git stash save 'some message'

Cela enregistrera vos modifications actuelles sur le côté de votre liste de réserve. Ci-dessus, la version la plus explicite de la commande stash, permettant à un commentaire de décrire ce que vous stockez. Vous pouvez également simplement exécuter git stash et rien d'autre, mais aucun message ne sera stocké.

Vous pouvez parcourir votre liste de cachettes avec ...

git stash list

Cela vous montrera toutes vos cachettes, les branches sur lesquelles elles ont été faites, le message et au début de chaque ligne, ainsi que l'identifiant de cette cachette qui ressemble à ceci stash@{#} où # est sa position dans le tableau des cachettes. .

Pour restaurer un stash (ce qui peut être fait sur n'importe quelle branche, peu importe où le stash a été créé à l'origine), vous devez simplement exécuter ...

git stash apply stash@{#}

De nouveau, il y a # la position dans le tableau de stash. Si la cachette que vous souhaitez restaurer se trouve dans la position 0, c'est-à-dire s'il s'agissait de la cachette la plus récente. Ensuite, vous pouvez simplement exécuter la commande sans spécifier la position de cache, git supposera que vous entendez le dernier: git stash apply.

Ainsi, par exemple, si je me trouve sur la mauvaise branche, je peux exécuter la séquence de commandes suivante.

git stash
git checkout <correct_branch>
git stash apply

Dans votre cas, vous avez déplacé un peu plus de branches, mais la même idée s’applique.

J'espère que cela t'aides.

162
eddiemoya

Je pense que tu cherches ça

git reset --soft HEAD~1

Il annule le dernier engagement tout en conservant les modifications apportées à cet engagement dans la mise en scène.

59
Sudhanshu Jain

Oui, vous pouvez supprimer votre commit sans supprimer les modifications: git reset @ ~

35
DURGESH Chaurasiya

Pour ceux qui utilisent zsh, vous devrez utiliser les éléments suivants:

git reset --soft HEAD\^

Expliqué ici: https://github.com/robbyrussell/oh-my-zsh/issues/449

Dans le cas où l'URL devient morte, la partie importante est:

Escape the ^ dans votre commande

Vous pouvez également utiliser HEAD ~ pour ne pas devoir y échapper à chaque fois.

8
Greg Hilston

Dans mon cas, j'ai déjà poussé à la repo. Aie!

Vous pouvez annuler un commit spécifique tout en conservant les modifications dans vos fichiers locaux en procédant comme suit:

git revert -n <sha>

De cette façon, je pouvais conserver les modifications dont j'avais besoin et annuler un commit qui avait déjà été poussé.

6
Wim Feijen

Utiliser git 2.9 (précisément 2.9.2.windows.1) git reset HEAD^ demande plus; pas sûr de ce qui est attendu entrée ici. S'il vous plaît se référer ci-dessous capture d'écran

enter image description here

Vous avez trouvé une autre solution git reset HEAD~#numberOfCommits en utilisant laquelle nous pouvons choisir de sélectionner le nombre de commits locaux que vous souhaitez réinitialiser en conservant vos modifications intactes. Par conséquent, nous avons l'occasion de jeter tous les commits locaux ainsi qu'un nombre limité de commits locaux.

Voir ci-dessous les captures d'écran montrant git reset HEAD~1 en action: enter image description here

enter image description here

3
nkharche

Une autre façon de le faire.

Ajoutez une validation en plus de la validation temporaire, puis procédez comme suit:

git rebase -i

Pour fusionner deux commits en un (la commande ouvrira un fichier texte avec des instructions explicites, éditez-le).

2
Ruslan Osipov

Vous recherchez soit _git reset HEAD^ --soft_ ou _git reset HEAD^ --mixed_.

La commande de réinitialisation comporte 3 modes, comme indiqué dans le docs :

git reset HEAD^ --soft

annuler le _git commit_. Les modifications existent toujours dans l’arbre de travail (dossier du projet) + l’index (--cached)

git reset HEAD^ --mixed

annuler _git commit_ + _git add_. Des modifications existent toujours dans l’arbre de travail

git reset HEAD^ --hard

Comme si vous n'aviez jamais apporté ces modifications à la base de code. Les changements ont disparu de l'arbre de travail.

2
Bar Horing