Comment faire pour revenir plusieurs commits git?
J'ai un dépôt git qui ressemble à ceci:
A -> B -> C -> D -> HEAD
Je veux la tête de la direction générale pour pointer vers Un, c'est à dire je veux, B, C, D, et la TÊTE de disparaître, et je veux la tête, synonyme de A.
Ça sonne comme je peux soit essayer de rebase (ne s'applique pas, puisque j'ai poussé les changements entre les deux), ou revenir en arrière. Mais comment puis-je revenir plusieurs engage? Dois-je revenir un à un? La commande est-elle importante?
- Si vous voulez juste pour réinitialiser la télécommande, vous pouvez tabasser avec quoi que ce soit! Mais permettez-nous d'utiliser la quatrième commettre: il y a
git push -f HEAD~4:master
(en supposant que la distance n'est le maître). Oui, vous pouvez le pousser à commettre tout comme ça. - Si les gens ont tiré, vous devez faire un commit qui revient changements à l'aide de
git revert
. - L'utilisation de git show TÊTE~4 pour vous assurer que vous êtes en poussant à droite de la télécommande
- Double Possible de Comment faire pour annuler le dernier commit(s) dans Git?
- "L'ordonnance est-elle importante?" Oui, si l'engage influent sur les mêmes lignes dans les mêmes fichiers. Ensuite, vous devriez commencer à revenir le plus récent s'engager, et de travailler votre chemin de retour.
Vous devez vous connecter pour publier un commentaire.
L'expansion de ce que j'ai écrit dans un commentaire
La règle générale est que vous ne devriez pas réécrire (changement) de l'histoire que vous avez publié, parce que quelqu'un peut avoir basé leur travail sur elle. Si vous réécrivez (changement) de l'histoire, vous ferez des problèmes avec la fusion de leurs modifications et mise à jour pour eux.
Donc la solution est de créer un nouveau commit qui annuler les modifications apportées que vous voulez vous débarrasser de. Vous pouvez faire cela en utilisant git revert commande.
Vous avez la situation suivante:
(flèches se réfère ici à la direction du pointeur: le "parent" de référence dans le cas de livraisons, le haut de validation dans le cas du chef de la direction générale (direction de la ref), et le nom de la branche, dans le cas de la TÊTE de référence).
Ce dont vous avez besoin pour créer est la suivante:
où "[(BCD)^-1]" signifie s'engager à ce que annuler les modifications apportées dans commet B, C, D. les Mathématiques nous dit que (BCD)^-1 = D^-1 C^-1 B^-1, de sorte que vous pouvez prendre la situation à l'aide des commandes suivantes:
Une solution alternative serait de la caisse contenu de commettre Un, et de s'engager dans cet état:
Ensuite, vous avez la situation suivante:
Le commettre Un " a le même contenu que de commettre Un, mais il est un autre commit (message de commit, de parents, d'engager date).
La solution par Jeff Ferland, modifié par Charles Bailey s'appuie sur la même idée, mais utilise git reset:
git checkout -f A -- .
pas à supprimer ces derniers, vous devrez le faire manuellement. J'ai appliqué cette stratégie aujourd'hui, grâce Jakubgit clean
est votre ami.--
à être nécessaire pour séparer le nom de la branche de pathspec. Le.
signifie "répertoire courant", et parce que les chemins sont relatifs au top irectory d'un projet, ici, il s'agit de vérifier l'ensemble du projet, tous les fichiers d'un projet.foo
(commutateur de direction) ou de caisse fichier foo (à partir de l'index).--
est utilisé pour lever l'ambiguïté, par exemplegit checkout -- foo
est toujours à propos de fichier.git revert --no-commit D C B
git revert
ne pas accepter de multiples s'engage; il est tout à fait nouveau plus.git reset --soft @{1}
solution en haut? C'est clairement la meilleure solution au problème.git checkout -f A -- .
je pense que cela signifie "vérifier les changements de commettre Un pour le répertoire courant sans entrer dans détaché de la TÊTE mode", en gros, vous restez maître, mais d'apporter les modifications de commettre Un à l'actuelle place dans le temps. Au moins, c'est ainsi que j'interprète, s'il vous plaît, corrigez-moi si je me trompe.A
état.git revert no-commit B..
(dans le terminal d'un environnement de développement intégré), puis-je utiliser l'IDE de commettre , je reçois dans un décollement de la TÊTE de l'état. Est-ce un comportement normal, en général, ou est-ce sans doute parce que j'ai utilisé le terminal pourrevert
de commande et de l'IDE pourcommit
commande? En tout cas, je fixe détaché de la TÊTE parrebasing
comme décrit icigit checkout -f A -- .
n'a pas bien fonctionné pour moi. Quand j'ai essayé de pousser, je ne pouvais pas sans la fusion de la version à distance, ce qui n'est pas ce que je voulais. Je suis en train de défaire les derniers commits, donc je ne veux pas la version à distance fusionnées.$ git commit -m 'the commit message'
avec des guillemets, s'il vous plaît.$ git revert --no-commit D
fatal: bad revision 'D'
git revert
séquentielle s'engage (commettre D, C, B, ci-dessus), il en serait de même si nous negit reset --soft HEAD~3
droit? Alors que,git revert
peut être utilisé pour rétablir la non-séquentiel s'engage à droite? Commegit revert --no-commit D B A
?git revert
peut être utilisé pour rétablir la non-séquentiel s'engage (et est souvent utilisé de cette façon), mais il peut en résulter un conflit de fusion dont vous avez besoin pour résoudreerror: your index file is unmerged
. Cet outil est une fracture de la blague.Pour ce faire, vous avez juste à utiliser le revenir commande, en spécifiant la plage de commits que vous voulez obtenir est revenue.
En tenant compte de votre exemple, vous auriez à le faire (en supposant que vous êtes sur la branche "master"):
Cela va créer un nouveau commit dans votre local par l'inverse de la validation de B, C et D (en ce sens qu'il permet d'annuler les modifications introduites par ces commits):
git revert --no-commit HEAD~2..
est un peu plus idiomatiques façon de le faire. Si vous êtes sur la branche master, pas besoin de préciser maître. Le--no-commit
option permet git tenter de revenir tous les commits à la fois, au lieu de salir l'histoire avec de multiplesrevert commit ...
messages (en supposant que c'est ce que vous voulez).master~3
.--no-commit
(de sorte que vous obtenez une distinct de s'engager pour chacun de revenir), et puis écraser tous ensemble dans un rebase interactif. Le combiné message de commit va contenir l'ensemble de la SHAs, et vous pouvez les organiser comme bon vous semble à l'aide de votre favori message de validation de l'éditeur.Propre façon que j'ai trouvé utile
Cette commande rétablit les 3 derniers s'engage avec un seul commit.
Aussi de ne pas réécrire l'histoire.
git commit
à partir de là va réellement faire la livraison.HEAD~3..
est le même queHEAD~3..HEAD
Similaire à Jakub réponse, cela vous permet de sélectionner facilement consécutives s'engage à revenir.
B^..HEAD
, sinon B est exclue.git revert --no-commit B^..HEAD
ougit revert --no-commit A..HEAD
Qui servira de revenir pour eux tous à la fois. Donner un bon message de commit.
HEAD
à ressembler àA
puis il a sûrement besoin de l'indice de match, afin degit reset --soft D
est probablement plus approprié.git checkout A
puisgit commit
ci-dessus ne fonctionne pas pour moi, mais cette réponse n'.git reset --mixed D
nécessaire? Précisément pourquoireset
? Est-ce parce que, sans remettre à D, qui, la TÊTE dans Un, causant B, C, et D être "bancale" et le garbage collector -- qui n'est pas ce qu'il veut? Mais alors, pourquoi--mixed
? Vous avez déjà répondu "--soft
la réinitialisation de ne pas déplacer l'index..." par le déplacement de l'index, cela signifie que l'indice contiendra D du changement, tandis que le Répertoire de Travail contiendra les modifications -- cette façon, ungit status
ougit diff
(qui compare l'Indice [D] pour le Répertoire de Travail [A]) afficher la substance; que l'utilisateur va partir D retour à Un?Abord, assurez-vous que votre copie de travail n'est pas modifié. Alors:
et puis il suffit de s'engager. N'oubliez pas de documenter ce qui est la raison pour revenir.
error: cannot apply binary patch to 'some/image.png' without full index line error: some/image.png: patch does not apply
git diff --binary HEAD commit_sha_you_want_to_revert_to | git apply
git revert A..Z
vous obtiendrezerror: commit X is a merge but no -m option was given.
Je suis tellement frustré que cette question ne peut être répondu. Toute autre question est par rapport à comment rétablir correctement et de préserver l'histoire. Cette question, dit "je veux la tête de la direction générale pour pointer vers Un, c'est à dire je veux, B, C, D, et la TÊTE de disparaître et je veux la tête, synonyme de A."
J'ai beaucoup appris à la lecture de Jakub post, mais certains gars dans la société (avec l'accès à pousser notre "test de la" branche sans la Pull-Request) ont poussé comme 5 bad s'engage à essayer de réparer et de fixer et réparer une erreur qu'il a fait 5 s'engage auparavant. Non seulement cela, mais un ou deux Pull Demandes ont été acceptées, qui étaient mauvais. Pour l'oublier, j'ai trouvé le dernier commit (abc1234) et juste couru le script de base:
J'ai dit que les 5 autres gars qui travaillent dans ce repo de mieux prendre note de leurs changements au cours des quelques dernières heures et Essuyez/Re-Branche depuis le dernier test. Fin de l'histoire.
git push --force-with-lease
, qui va réécrire l'histoire seulement si personne n'a commis à la direction générale à la suite ou à l'intérieur de la plage de la s'engage à vapourize. Si d'autres personnes ont utilisé la branche, puis son histoire ne doit jamais être réécrite, et que la livraison ne devrait tout simplement être visiblement revenue.git push -f
à la placegit push --force-with-lease
Semble évident, mais ce n'est pas la façon dont votre commentaire lire. Il moreso semblait qu'il était d'une ligne, rien-d'autre-requis, la solution exacte. Je suis d'accord que le fait de modifier la dernière ligne de ma réponse offrir cette protection supplémentaire (et de travail). Je viens personnellement de ne pas le faire, sauf si il y avait des gens à qui je n'ai pas le contrôle de travailler sur le code. Donc, votre point est bon pour quoi que ce soit open source ou multi-ministériel pour vous. Si je ne suis pas Git Savant, et de ne même pas savoir qui commande, lol.C'est une expansion de l'une des solutions proposées dans Jakub la réponse de
J'ai été confronté à une situation où les commits j'avais besoin de faire reculer ont été quelque peu complexe, avec plusieurs de la commet en cours de fusion s'engage, et je voulais éviter d'avoir à réécrire l'histoire. Je n'ai pas été en mesure d'utiliser une série de
git revert
commandes parce que j'ai finalement couru dans les conflits entre la réversion des modifications en cours d'ajout. J'ai fini par utiliser les étapes suivantes.Tout d'abord, vérifiez le contenu de la cible de commettre tout en laissant la TÊTE à l'extrémité de la branche:
(Le -- permet de s'assurer
<target-commit>
est interprétée comme une validation plutôt que d'un fichier; le . désigne le répertoire courant.)Ensuite, de déterminer quels fichiers ont été ajoutés dans la commet pas être annulée, et doivent donc être supprimés:
Les fichiers qui ont été ajoutés doivent apparaître avec Un "a" au début de la ligne, et il n'y aura pas d'autres différences. Maintenant, si des fichiers doivent être supprimés, en scène ces fichiers pour les supprimer:
Enfin, valider la réversion:
Si vous le souhaitez, assurez-vous que nous sommes de retour à l'état désiré:
Il devrait y avoir aucune différence.
git
TÊTE avec juste le bout de la branche?Le moyen facile de revenir d'un groupe de commits sur le référentiel partagé (que les gens utilisent et vous souhaitez préserver l'histoire) est d'utiliser
git revert
en conjonction avec gitrev-list
. Ce dernier vous fournira une liste de commits, l'ancien va faire revenir de lui-même.Il y a deux façons de le faire. Si vous voulez revenir plusieurs s'engage dans un seul commit utilisation:
cela reviendra un groupe de commits que vous avez besoin, mais laisser tous les changements sur votre arbre de travail, vous vous engager à tous, comme d'habitude.
Une autre option est d'avoir un seul commit par revenue changement:
Par exemple, si vous avez un commit arbre comme
d'annuler les changements d' eee à bbb, exécutez
Aucun de ceux qui ont travaillé pour moi, j'ai donc eu trois s'engage à revenir (les trois derniers commits), j'ai donc fait:
A fonctionné comme un charme 🙂
À mon avis un très facile à nettoyer et pourrait être:
revenir à Une
point de maître, à la tête de l'état actuel de
enregistrer
Si vous souhaitez temporairement revenir les commits d'une fonction, alors vous pouvez utiliser la série de commandes suivantes.
Voici comment cela fonctionne
git log --pretty=oneline | grep 'feature_name' | cut-d '' -f1 | xargs -n1 git revert --no-edit