J'ai un dépôt git qui ressemble à ceci:
A -> B -> C -> D -> HEAD
Je veux que le chef de la branche pointe vers A, c'est-à-dire que je veux que B, C, D et HEAD disparaissent et je veux que head soit synonyme de A.
Il semble que je puisse soit essayer de rebaser (ne s'applique pas, car j'ai poussé les changements entre les deux), soit revenir en arrière. Mais comment annuler plusieurs validations? Dois-je revenir un à la fois? La commande est-elle importante?
git
commit
git-revert
Facture
la source
la source
git push -f HEAD~4:master
(en supposant que la branche distante est master). Oui, vous pouvez pousser n'importe quel commit comme ça.git revert
.Réponses:
Développer ce que j'ai écrit dans un commentaire
La règle générale est que vous ne devez pas réécrire (modifier) l'historique que vous avez publié, car quelqu'un a peut-être basé son travail dessus. Si vous réécrivez (modifiez) l'historique, vous rencontrez des problèmes avec la fusion de leurs modifications et leur mise à jour.
La solution consiste donc à créer un nouveau commit qui annule les modifications dont vous souhaitez vous débarrasser. Vous pouvez le faire en utilisant la commande git revert .
Vous avez la situation suivante:
(les flèches se réfèrent ici à la direction du pointeur: la référence "parent" dans le cas des validations, la validation supérieure dans le cas de la tête de branche (référence de branche) et le nom de la branche dans le cas de la référence HEAD).
Ce que vous devez créer est le suivant:
où "[(BCD) ^ - 1]" signifie le commit qui annule les changements dans les commits B, C, D. Les mathématiques nous disent que (BCD) ^ - 1 = D ^ -1 C ^ -1 B ^ -1, donc vous pouvez obtenir la situation requise en utilisant les commandes suivantes:
Une autre solution consisterait à extraire le contenu du commit A et à valider cet état:
Vous auriez alors la situation suivante:
Le commit A 'a le même contenu que le commit A, mais est un commit différent (message de commit, parents, date de commit).
La solution de Jeff Ferland, modifiée par Charles Bailey s'appuie sur la même idée, mais utilise git reset :
la source
git checkout -f A -- .
ne les supprimera pas, vous devrez le faire manuellement. J'ai appliqué cette stratégie maintenant, merci Jakubgit checkout foo
peut signifier une branche de paiementfoo
(passer à une branche) ou un fichier de paiement foo (à partir de l'index).--
est utilisé pour lever l'ambiguïté, par exemplegit checkout -- foo
concerne toujours le fichier.git revert --no-commit D C B
git revert
n'avez pas accepté plusieurs validations; c'est un ajout tout à fait nouveau.Voie propre que j'ai trouvée utile
Cette commande annule les 3 dernières validations avec une seule validation.
Ne réécrit pas non plus l'historique.
la source
git commit
à partir de là, fera le commit.HEAD~3..
est le même queHEAD~3..HEAD
Pour ce faire, il vous suffit d'utiliser la commande revert , en spécifiant la plage de validations que vous souhaitez annuler.
En tenant compte de votre exemple, vous devriez le faire (en supposant que vous êtes sur la branche «maître»):
Cela va créer un nouveau commit dans votre local avec le commit inverse de B, C et D (ce qui signifie qu'il annulera les changements introduits par ces commits):
la source
git revert --no-commit HEAD~2..
est une façon un peu plus idiomatique de le faire. Si vous êtes sur la branche master, pas besoin de spécifier à nouveau master. L'--no-commit
option permet à git d'essayer de rétablir toutes les validations à la fois, au lieu de joncher l'historique de plusieursrevert commit ...
messages (en supposant que c'est ce que vous voulez).master~3
.--no-commit
(donc vous obtenez un commit séparé pour chaque retour), puis de les écraser tous ensemble dans un rebase interactif. Le message de validation combiné contiendra tous les SHA, et vous pouvez les organiser comme bon vous semble en utilisant votre éditeur de message de validation préféré.Semblable à la réponse de Jakub, cela vous permet de sélectionner facilement des validations consécutives à annuler.
la source
B^..HEAD
cas, sinon B est exclu.git revert --no-commit B^..HEAD
ougit revert --no-commit A..HEAD
Cela agira comme un retour pour tous à la fois. Donnez un bon message de validation.
la source
HEAD
ressembler,A
il veut probablement que l'index correspondegit reset --soft D
est donc probablement plus approprié.git checkout A
alorsgit commit
ci-dessus n'a pas fonctionné pour moi, mais cette réponse a fonctionné.git reset --mixed D
requis? Plus précisément pourquoireset
? Est-ce parce que, sans réinitialiser D, HEAD pointerait A, faisant en sorte que B, C et D "se balancent" et soient récupérés - ce qui n'est pas ce qu'il veut? Mais alors pourquoi--mixed
? Vous avez déjà répondu "la--soft
réinitialisation ne déplace pas l'index ..." Donc, en déplaçant l'index, cela signifie que l'index contiendra les changements de D, tandis que le répertoire de travail contiendra les changements de A - de cette façon agit status
ougit diff
(qui compare Index [D] à Le répertoire de travail [A]) montrera la substance; cet utilisateur passe de D à A?Assurez-vous d'abord que votre copie de travail n'est pas modifiée. Alors:
et puis juste engager. N'oubliez pas de documenter la raison du retour.
la source
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é de ne pas pouvoir répondre à cette question. Toutes les autres questions concernent la manière de revenir correctement et de préserver l'histoire. Cette question dit "Je veux que le chef de la branche pointe vers A, c'est-à-dire que je veux que B, C, D et HEAD disparaissent et je veux que head soit synonyme de A."
J'ai beaucoup appris en lisant le post de Jakub, mais un gars de l'entreprise (avec accès pour pousser à notre branche "testing" sans Pull-Request) a poussé comme 5 mauvais commits essayant de corriger et de corriger et de corriger une erreur qu'il a faite il y a 5 commits. Non seulement cela, mais une ou deux demandes d'appel ont été acceptées, ce qui était maintenant mauvais. Alors oubliez ça, j'ai trouvé le dernier bon commit (abc1234) et je viens d'exécuter le script de base:
J'ai dit aux 5 autres gars travaillant dans ce repo qu'ils feraient mieux de noter leurs changements pour les dernières heures et Wipe / Re-Branch des derniers tests. Fin de l'histoire.
la source
git push --force-with-lease
réécrire l'historique uniquement si personne d'autre ne s'est engagé dans la branche après ou dans la plage des validations à vaporiser. Si d'autres personnes ont utilisé la branche, son histoire ne doit jamais être réécrite et le commit doit simplement être visiblement annulé.Il s'agit d'une extension d'une des solutions fournies dans la réponse de Jakub
J'étais confronté à une situation où les validations dont j'avais besoin pour revenir en arrière étaient quelque peu complexes, plusieurs des validations étant des validations de fusion, et je devais éviter de réécrire l'historique. Je n'ai pas pu utiliser une série de
git revert
commandes car j'ai finalement rencontré des conflits entre les modifications de réversion ajoutées. J'ai fini par utiliser les étapes suivantes.Tout d'abord, vérifiez le contenu de la validation cible tout en laissant HEAD à la pointe de la branche:
(Le - s'assure
<target-commit>
est interprété comme un commit plutôt que comme un fichier; le. Fait référence au répertoire courant.)Ensuite, déterminez quels fichiers ont été ajoutés dans les validations annulées 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 ne doit pas y avoir d'autres différences. Maintenant, si des fichiers doivent être supprimés, procédez à leur suppression:
Enfin, validez la réversion:
Si vous le souhaitez, assurez-vous que nous sommes de retour à l'état souhaité:
Il ne devrait pas y avoir de différences.
la source
git
TÊTER avec le bout de la branche?Le moyen facile de rétablir un groupe de validations sur un référentiel partagé (que les gens utilisent et que vous souhaitez conserver l'historique) est d'utiliser
git revert
en conjonction avec gitrev-list
. Ce dernier vous fournira une liste de commits, le premier effectuera le retour lui-même.Il y a deux façons de procéder. Si vous souhaitez annuler plusieurs validations en une seule utilisation:
cela annulera un groupe de validations dont vous avez besoin, mais laissez toutes les modifications dans votre arborescence de travail, vous devez toutes les valider comme d'habitude.
Une autre option consiste à avoir un seul commit par modification annulée:
Par exemple, si vous avez un arbre de validation comme
pour annuler les modifications de eee à bbb , exécutez
la source
Aucun de ceux-ci ne fonctionnait pour moi, j'ai donc eu trois commits à annuler (les trois derniers commits), alors j'ai fait:
A fonctionné comme un charme :)
la source
À mon avis, un moyen très simple et propre pourrait être:
retourner à A
diriger la tête du maître vers l'état actuel
enregistrer
la source
git checkout master; git reset --hard A
? Sinon, pourriez-vous expliquer un peu plus ce que cela fait?Si vous souhaitez annuler temporairement les validations d'une fonction, vous pouvez utiliser la série de commandes suivantes.
Voici comment ça marche
git log --pretty = en ligne | grep 'nom_fonction' | coupe -d '' -f1 | xargs -n1 git revert --no-edit
la source