web-dev-qa-db-fra.com

Git pull après mise à jour forcée

Je viens d'écraser quelques commits avec git rebase et de faire un git Push --force (qui est diabolique, je le sais).

Maintenant, les autres ingénieurs en logiciel ont un historique différent et quand ils font un git pull, Git fusionne. Y a-t-il un moyen de résoudre ce problème, sauf de faire un rm my-repo; git clone [email protected]:my-repo.git?

J'ai besoin de quelque chose comme l'opposé de git Push --force, mais git pull --force n'a pas donné les résultats escomptés.

280
iblue

Recevoir les nouveaux commits

git fetch

Réinitialiser

Vous pouvez réinitialiser le commit pour une branche locale en utilisant git reset.

Pour changer le commit d'une branche locale:

git reset Origin/master --hard

Soyez prudent cependant, comme le dit la documentation:

Réinitialise l'index et l'arbre de travail. Toute modification apportée aux fichiers suivis dans l’arbre de travail depuis <commit> est ignorée.

Si vous souhaitez conserver les modifications locales, modifiez plutôt --soft. Ce qui mettra à jour l'historique de validation de la branche, mais ne modifiera aucun fichier du répertoire de travail (et vous pourrez ensuite les valider).

Rebase

Vous pouvez rejouer vos commits locaux au-dessus de tout autre commit/branche en utilisant git rebase:

git rebase -i Origin/master

Ceci appellera rebase en mode interactif où vous pourrez choisir comment appliquer chaque commit individuel qui ne fait pas partie de l'historique sur lequel vous rebassez.

Si les commits supprimés (avec git Push -f) ont déjà été entrés dans l'historique local, ils seront répertoriés en tant que commits qui seront réappliqués - ils devront être supprimés dans le cadre de la base ou ils seront simplement ré-appliqués. -inclus dans l'historique de la branche - et réapparaît dans l'historique à distance lors du prochain envoi.

Utilisez l’aide git command --help pour plus de détails et d’exemples sur les commandes ci-dessus (ou autres).

444
AD7six

Cela ne corrigera pas les branches qui contiennent déjà le code que vous ne voulez pas (voir ci-dessous pour savoir comment le faire), mais si elles ont tiré une branche et veulent maintenant qu'elle soit propre (et non "en avance"), Origine/une branche) alors vous simplement:

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch Origin/base-branch  # recreating branch with correct commits

Remarque: vous pouvez combiner tous ces éléments en mettant && entre eux.

Note 2: Florian a mentionné cela dans un commentaire, mais qui lit les commentaires quand on cherche des réponses?

Remarque 3: Si vous avez des branches contaminées, vous pouvez en créer de nouvelles à partir de la nouvelle "branche stupide" et procéder simplement à un tri sélectif.

Ex:

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

Feature-new est maintenant votre branche sans les commits supplémentaires (éventuellement mauvais)!

15
Tom Prats