Question

J'ai un dépôt git qui ressemble à ceci:

A -> B -> C -> D -> HEAD

Je veux la tête de la branche pour pointer vers A, je veux dire B, C, D, et la tête à disparaître et je veux tête soit synonyme de A.

On dirait que je peux soit essayer de rebasage (ne concerne pas, puisque je l'ai poussé les changements entre les deux), ou revenir. Mais comment puis-je retourne plusieurs commits? Est-ce que je retourne un à la fois? L'ordre important?

Était-ce utile?

La solution

L'expansion que j'ai écrit dans un commentaire

La règle générale est que vous ne devriez pas réécrire (changement) l'histoire que vous avez publié, parce que quelqu'un aurait pu fondé leur travail sur elle. Si vous réécrivez (changement) l'histoire, vous causer des problèmes avec la fusion de leurs changements et la mise à jour pour eux.

La solution est donc de créer un nouveau commit qui modifications revient que vous voulez vous débarrasser. Vous pouvez le faire en utilisant git

Vous avez la situation suivante:

A <-- B  <-- C <-- D                                               <-- master <-- HEAD

(flèches ici fait référence à la direction du pointeur: la référence « parent » dans le cas de commits, le haut engage dans le cas de la tête de la branche (ref branche), et le nom de la branche dans le cas de référence HEAD ).

Ce que vous devez créer est le suivant:

A <-- B  <-- C <-- D <-- [(BCD)^-1]                   <-- master <-- HEAD

où "[(BCD) ^ - 1]" désigne la commettras que Revient changements dans engage B, C, D. Mathématiques nous dit que (BCD) ^ - 1 = D ^ -1 C ^ -1 B ^ - 1, de sorte que vous pouvez obtenir la situation requise en utilisant les commandes suivantes:

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message"

Autre solution serait de la caisse contenu de commettre un, et engager cet état:

$ git checkout -f A -- .
$ git commit -a

Ensuite, vous avez la situation suivante:

A <-- B  <-- C <-- D <-- A'                       <-- master <-- HEAD

Les comi A » a le même contenu que commettre un, mais est un autre commit (message de validation, les parents, date de livraison).

La solution par Jeff Ferland, modifié par Charles Bailey se base sur la même idée, mais utilise git reset :

$ git reset --hard A
$ git reset --soft @{1}  # (or ORIG_HEAD), which is D
$ git commit

Autres conseils

Pour ce faire il vous suffit d'utiliser le revert commande, spécifiant la plage de commits que vous voulez faire est revenu.

La prise en compte de votre exemple, vous devez le faire (en supposant que vous êtes sur la branche « maître »):

git revert master~3..master

Cela va créer un nouveau commit dans votre local avec l'inverse validation de B, C et D (ce qui signifie qu'elle annule les modifications introduites par ces commits):

A <- B <- C <- D <- BCD' <- HEAD

propre chemin que je trouve utile

git revert --no-commit HEAD~3..

Cette commande retourne 3 derniers commits avec un seul engagement.

Aussi ne pas réécrire l'histoire.

Tout comme la réponse de Jakub, ce qui vous permet de sélectionner facilement commits consécutives de revenir.

# revert all commits from B to HEAD, inclusively
$ git revert --no-commit B..HEAD  
$ git commit -m 'message'
git reset --hard a
git reset --mixed d
git commit

qui agira comme un revert pour tous à la fois. Donnez un bon message de commit.

Tout d'abord assurez-vous que votre copie de travail ne soit pas modifiée. Puis:

git diff HEAD commit_sha_you_want_to_revert_to | git apply

et puis juste engager. Ne pas oublier de documenter ce qui est la raison pour Revert.

Je suis tellement frustré que cette question ne peut pas être simplement répondu. Chaque autre question est en ce qui concerne la façon de revenir correctement et de préserver l'histoire. Cette question dit "Je veux la tête de la branche au point A, à savoir que je veux B, C, D, et HEAD disparais et je veux la tête soit synonyme de A."

git checkout <branch_name>
git reset --hard <commit Hash for A>
git push -f

J'ai beaucoup appris à lire le poste de Jakub, mais un gars dans l'entreprise (avec accès à pousser à notre branche « test » sans traction demande) poussé comme 5 mauvais engage à essayer de réparer et de fixer et de corriger une erreur qu'il a commise 5 commet il y a. Non seulement cela, mais une ou deux demandes ont été acceptées Pull, qui étaient maintenant mauvais. Alors oubliez, j'ai trouvé la dernière bonne commit (abc1234) et juste couru le script de base:

git checkout testing
git reset --hard abc1234
git push -f

J'ai dit aux 5 autres gars qui travaillent dans ce repo qu'ils mieux prendre note de leurs changements au cours des dernières heures et Wipe / Re-Direction de la dernière des tests. Fin de l'histoire.

Ceci est une extension de l'une des solutions proposées dans la réponse de Jakub

Je suis face à une situation où les commits je avais besoin de revenir étaient quelque peu complexe, avec plusieurs des commits être fusion engage, et je devais éviter de réécrire l'histoire. Je n'étais pas en mesure d'utiliser une série de commandes de git revert parce que je suis tombé sur la suite des conflits entre le retour change ajouté. J'ai fini en procédant comme suit.

Tout d'abord, vérifiez le contenu de la cible engager tout en laissant la tête à la pointe de la branche:

$ git checkout -f <target-commit> -- .

(Le - fait <target-commit> vous est interprété comme un engagement plutôt qu'un fichier, le fait référence au répertoire courant.).

Ensuite, déterminez quels fichiers ont été ajoutés dans les commits sont annulées, et doivent donc être supprimés:

$ git diff --name-status --cached <target-commit>

Les fichiers qui ont été ajoutés devrait apparaître avec un « A » au début de la ligne, et il devrait y avoir aucune autre différence. Maintenant, si les fichiers doivent être supprimés, scène ces fichiers à supprimer:

$ git rm <filespec>[ <filespec> ...]

Enfin, valider le retour:

$ git commit -m 'revert to <target-commit>'

Si vous le souhaitez, assurez-vous que nous sommes de retour à l'état désiré:

$git diff <target-commit> <current-commit>

Il devrait y avoir aucune différence.

La façon facile de revenir un groupe de commits sur référentiel partagé (que les gens utilisent et que vous voulez préserver l'histoire) est d'utiliser git revert conjointement avec rev-list git. Ce dernier ne vous fournira une liste des commits, l'ancien fera le revert lui-même.

Il y a deux façons de le faire. Si vous voulez que le multiple revert engage en une seule utilisation commit:

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert -n $i; done

retournera un groupe de commits dont vous avez besoin, mais laissez tous les changements sur votre arbre de travail, vous devez les engager tout comme d'habitude.

Une autre option est d'avoir un seul changement par commettras est revenu:

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-edit -s $i; done

Par exemple, si vous avez un commit arbre comme

 o---o---o---o---o---o--->    
fff eee ddd ccc bbb aaa

pour annuler les modifications de eee bbb , exécutez

for i in `git rev-list eee^..bbb`; do git revert --no-edit -s $i; done

Aucun de ceux travaillé pour moi, donc j'ai eu trois commits à trois (, reviennent derniers commits), donc je l'ai fait:

git revert HEAD
git revert HEAD~2
git revert HEAD~4
git rebase -i HEAD~3 # pick, squash, squash

A travaillé comme un charme:)

À mon avis, un moyen très simple et propre pourrait être:

revenir à A

git checkout -f A

la tête de point de maître à l'état actuel

git symbolic-ref HEAD refs/heads/master

Enregistrer

git commit

Si vous souhaitez revenir temporairement les commits d'une fonction, vous pouvez utiliser la série de commandes suivantes.

Voici comment cela fonctionne

git log = --pretty de oneline | grep 'feature_name' | cut -d '' -f1 | xargs git -n1-edit revenir --no

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top