J'avais un dépôt qui avait de mauvais commits (D, E et F pour cet exemple).
Master ABCDEF et origine / master
J'ai modifié le référentiel local spécifiquement avec a git reset --hard
. J'ai pris une branche avant la réinitialisation alors maintenant j'ai un dépôt qui ressemble à:
A-B-C master
\ D-E-F old_master
A-B-C-D-E-F origin/master
Maintenant, j'avais besoin de certaines parties de ces mauvais commits, alors j'ai choisi les bits dont j'avais besoin et j'ai fait de nouveaux commits alors maintenant, j'ai les éléments suivants localement:
A-B-C-G-H master
\ D-E-F old_master
Maintenant, je veux pousser cet état de choses au référentiel distant. Cependant, lorsque j'essaie de faire un git push
Git, je me donne poliment le coup de pinceau:
$ git push origin +master:master --force
Total 0 (delta 0), reused 0 (delta 0)
error: denying non-fast forward refs/heads/master (you should pull first)
To [email protected]:myrepo.git
! [remote rejected] master -> master (non-fast forward)
error: failed to push some refs to '[email protected]:myrepo.git'
Comment obtenir le référentiel distant pour prendre l'état actuel du référentiel local?
git push -force
plus attentivement .Réponses:
Si forcer une poussée n'aide pas ("
git push --force origin
" ou "git push --force origin master
" devrait être suffisant), cela peut signifier que le serveur distant refuse les poussées non rapides via la réception .denyNonFastForwards (voir git config pour la description manpage), ou via le crochet de mise à jour / pré-réception.Avec Git plus ancien, vous pouvez contourner cette restriction en supprimant "
git push origin :master
" (voir le ':' avant le nom de la branche), puis en recréant "git push origin master
" la branche donnée.Si vous ne pouvez pas changer cela, alors la seule solution serait au lieu de réécrire l'historique pour créer un commit annulant les modifications dans DEF :
la source
get revert HEAD~N
aidé.N
est le nombre de validations. Par exemple, si j'ai besoin du commit précédent, je vais utilisergit revert HEAD~1
Pour compléter la réponse de Jakub, si vous avez accès au serveur git distant dans ssh, vous pouvez aller dans le répertoire distant git et définir:
Revenez ensuite à votre référentiel local, essayez à nouveau de faire votre commit avec
--force
:Et enfin, rétablissez les paramètres du serveur dans l'état protégé d'origine:
la source
vi
sont fournies sur ce message SO: stackoverflow.com/a/43721579/2073804Au lieu de réparer votre branche "maître", il est beaucoup plus facile de l'échanger avec votre "maître souhaité" en renommant les branches. Voir https://stackoverflow.com/a/2862606/2321594 . De cette façon, vous ne laisseriez même aucune trace de plusieurs journaux de retour.
la source
Toute l'entreprise de réinitialisation de Git semblait loin de me compliquer les choses.
J'ai donc fait quelque chose le long des lignes pour obtenir mon dossier src dans l'état que j'avais il y a quelques commits
De cette façon, la situation dans le src est conservée dans un fichier tar et git est obligé d'accepter cet état sans trop jouer, le répertoire src est remplacé par l'état qu'il avait plusieurs validations il y a plusieurs années.
la source
Pour les utilisateurs de GitHub, cela a fonctionné pour moi:
git reset --hard <full_hash_of_commit_to_reset_to>
git push --force
Cela "corrigera" l'historique des branches sur votre machine locale et le serveur GitHub, mais quiconque a synchronisé cette branche avec le serveur depuis le mauvais commit aura l'historique sur leur machine locale. S'ils sont autorisés à envoyer directement à la branche, ces validations s'afficheront directement lors de la synchronisation.
Tout ce que tout le monde doit faire, c'est la
git reset
commande d'en haut pour "corriger" la branche sur sa machine locale. Bien sûr, ils devraient se méfier de tout commit local effectué sur cette branche après le hachage cible. Cherry pick / backup et réappliquez ceux-ci si nécessaire, mais si vous êtes dans une branche protégée, le nombre de personnes qui peuvent s'y engager directement est probablement limité.la source