web-dev-qa-db-fra.com

Annulation d'une partie d'un commit avec git

Je veux annuler un commit particulier dans git. Malheureusement, notre organisation utilise toujours CVS en tant que norme, donc lorsque je reviens à CVS, plusieurs validations git sont regroupées en une seule. Dans ce cas, j'aimerais souligner le git commit original, mais c'est impossible.

Existe-t-il une approche similaire à git add --patch qui me permettrait de modifier sélectivement les diffs pour décider quelles parties d'un commit retourner?

125
skiphoppy

Utilisez le --no-commit (-n) option pour git revert, puis supprimez les modifications, puis utilisez git add --patch:

$ git revert -n $bad_commit    # Revert the commit, but don't commit the changes
$ git reset HEAD .             # Unstage the changes
$ git add --patch .            # Add whatever changes you want
$ git commit                   # Commit those changes

Remarque: Les fichiers que vous ajoutez à l'aide de git add --patch sont les fichiers que vous souhaitez rétablir, pas les fichiers que vous souhaitez conserver.

199
mipadi

J'ai utilisé ce qui suit avec succès.

Commencez par annuler la validation complète (la place dans l'index) mais ne la validez pas.

git revert -n <sha1>  # -n is short for --no-commit

Ensuite, supprimez de manière interactive les BONNES modifications annulées de l'index

git reset -p          # -p is short for --patch  

Ensuite, validez la différence inverse des mauvais changements

git commit -m "Partially revert <sha1>..."

Enfin, les bonnes modifications annulées (qui n'ont pas été mises en scène par la commande de réinitialisation) sont toujours dans l'arborescence de travail. Ils doivent être nettoyés. Si aucune autre modification non validée n'est laissée dans l'arborescence de travail, cela peut être fait par

git reset --hard
36
user1338062

Personnellement, je préfère cette version, qui réutilise le message de validation généré automatiquement et donne à l'utilisateur la possibilité de modifier et de coller le mot "partiellement" avant de finalement valider.

# generate a revert commit
# note the hash printed to console on success
git revert --no-edit <hash to revert>

# undo that commit, but not its changes to the working tree
# (reset index to commit-before-last; that is, one graph entry up from HEAD)
git reset HEAD~1

# interactively add reversions
git add -p

# commit with pre-filled message
git commit -c <hash from revert commit, printed to console after first command>

# reset the rest of the current directory's working tree to match git
# this will reapply the excluded parts of the reversion to the working tree
# you may need to change the paths to be checked out
# be careful not to accidentally overwrite unsaved work
git checkout -- .
4
jeffcook2150

Solution:

git revert --no-commit <commit hash>
git reset -p        # every time choose 'y' if you want keep the change, otherwise choose 'n'
git commit -m "Revert ..."
git checkout -- .   # Don't forget to use it.
4

Une autre alternative (si votre version actuelle d'un fichier n'est pas trop éloignée de la version que vous essayez de rétablir) est d'obtenir le hachage du commit immédiatement avant celui que vous souhaitez restaurer partiellement ( de git log). Votre commande devient alors:

$ git checkout -p <hash_preceding_commit_to_revert> -- file/you/want/to/fix.ext

Cela modifie les fichiers dans votre arborescence de travail mais ne crée pas de commit, donc si vous êtes vraiment bourré, vous pouvez simplement recommencer avec git reset --hard -- file/you/want/to/fix.ext.

2
Walf

Vous pouvez utiliser git-revert -n, puis utiliser add --patch pour sélectionner les mecs.

1
William Pursell