Cette question est peut-être en double mais je n'en ai pas trouvé exactement la même.
Dans le dépôt git de notre équipe QA, je trouve souvent que les cas de test que j'ai ajoutés auparavant ont été perdus. et à partir de l'historique de la branche principale, je ne trouve plus mon commit.
La cause principale a été trouvée une fois lorsque j'ai comparé le journal de ma branche personnelle et le journal de la branche principale, et c'était la force push de quelqu'un, et le gars a admis qu'il n'était pas très familier avec git merge mais s'est dépêché de pousser l'option de force si utilisée.
Mais que se passe-t-il s'il n'y a pas de telle branche qui sauvegarde l'historique de ces commit? et chaque membre de l'équipe a retiré après quelques jours pour que l'historique des commits disparaisse à jamais.
Et même s'il existe une telle branche de sauvegarde, il faut beaucoup de temps pour comparer et savoir qui a fait la poussée de force.
Existe-t-il des moyens d'obtenir le journal de force push? Veuillez noter qu'en tant qu'employé normal, je ne suis pas le propriétaire / administrateur du serveur git, mais je me soucie de mes commits et je veux que ceux qui les suppriment soient avertis.
3 Réponses :
Il n'y a pas de moyen vraiment fiable dans git
lui-même de récupérer ce genre d'informations. (Il est possible que certains logiciels d'hébergement git puissent conserver des enregistrements de poussée de force de type reflog, mais je n'en ai pas connaissance; si vous utilisez un pack d'hébergement particulier, vous pouvez consulter sa documentation.)
En plus de trouver un clone qui n'a pas accepté la nouvelle histoire, vous pourriez également être en mesure d'obtenir les informations dont vous avez besoin à partir des reflogs d'un clone même après qu'il a accepté la nouvelle histoire - mais les reflogs sont locaux et temporaires, donc ce n'est pas garanti.
(Selon la façon dont votre télécommande est hébergée, vous pourriez également être en mesure de vous référer à ses reflogs, si elle les conserve et si vous pouvez y accéder. Mais même si tous ces si < / em> briser votre chemin, il n'y a aucune garantie, car les reflogs sont temporaires.)
C'est pourquoi git push -f
est un outil dangereux; et au risque d'être brutal, si la compréhension d'un développeur de git n'a pas progressé au point de comprendre à quel point c'est dangereux, alors ce développeur ne devrait pas avoir accès pour forcer la poussée vers des références partagées avec d'autres développeurs. p>
Vous pouvez configurer une télécommande git pour rejeter toutes les poussées non rapides (même si elles sont forcées); voir receive.denyNonFastForwards
dans la documentation git config
.
Si vous avez besoin d'un contrôle plus fin, vous devrez à nouveau compter sur le logiciel d'hébergement pour le fournir.
Vous ne pourrez pas obtenir l'historique des push de force, mais vous pourrez au moins espionner vos propres commits qui ont été écrasés. Depuis votre clone local, utilisez git fsck
:
(master) :~/repo$ git fsck --lost-found Checking object directories: 100% (256/256), done. dangling blob 6edc1e217eaab8f72f67bcec2e4d1dfde299971e dangling commit 9847c5942bf477989112ece202988bc3f8caad05 (master) :~/repo$ git merge 9847c59 // ... conflicts likely appear ... //
De là, vous pouvez résoudre les conflits et repousser vos modifications le cas échéant. Cela ne fonctionne pas si vous êtes sur un système différent de celui où vous avez effectué le commit, et même dans ce cas, vos commits locaux peuvent être perdus en raison de l'élagage si suffisamment de temps s'est écoulé.
Cette solution plutôt «hacky» peut être utile pour trouver des commits de modification forcés, même si je ne suis pas sûr que cela fonctionnerait dans toutes les situations possibles.
En supposant que vous êtes sur le dépôt distant (nu), pourrait afficher tous les commits stockés dans le reflog d'une branche particulière et les comparer aux commits d'un git log
normal. La différence devrait vous donner la force des commits push.
Notez que pour les dépôts nus, les reflogs doivent être activés .
À titre d'exemple, supposons que vous vous êtes engagé dans master, push, puis amendé et forcé - deux fois. Ensuite, vous auriez quatre commits au total (comme vu par le reflog), mais seulement deux dans votre journal actuel:
$ diff <(git log -g master | grep ^commit) <(git log master | grep ^commit) | grep "^<" < commit 5afa0cfe6e16d4d45088aeb226ed052a5ad72b87 < commit 8bb40a9d6da838e151c8653b8d6be2b7afeb1902
En bash, je peux alors montrer la différence entre les deux (en utilisant la substitution de processus):
$ git log -g master | grep ^commit # Show reflog of master commit 3f52cea357aaa6ba9db86c1526b025a7ee2906c1 (refs/remotes/origin/master, refs/heads/master) commit 5afa0cfe6e16d4d45088aeb226ed052a5ad72b87 commit 0334c6f8ba13c1465c855cf0b7cf6c79df487740 commit 8bb40a9d6da838e151c8653b8d6be2b7afeb1902 $ git log master | grep ^commit # Show log of master commit 3f52cea357aaa6ba9db86c1526b025a7ee2906c1 (refs/remotes/origin/master, refs/heads/master) commit 0334c6f8ba13c1465c855cf0b7cf6c79df487740 $ git reflog # for reference - HEAD@{0, 2} were force pushes 3f52cea (HEAD -> refs/heads/master) HEAD@{0}: push 5afa0cf HEAD@{1}: push 0334c6f HEAD@{2}: push 8bb40a9
Je diffère les deux sorties ci-dessus et je redirige vers grep
, de sorte que je puisse voir les commits qui ont été modifiés.
qu'entendez-vous par remote (bare)
? peut-il être obtenu si je suis un utilisateur normal qui n'a pas accès à la machine serveur git?
Les référentiels git utilisés comme une sorte de serveur centralisé sont généralement dépôts nus . La solution que j'ai présentée ne fonctionne que si vous avez un accès shell au référentiel distant.
Peut-être cherchez-vous
git reflog
(sur votre serveur "central")?Peut-être regardez ici ?
@andreee voulez-vous dire que le journal est toujours sur le serveur? si nous
tirons
localement, alors le journal des validations sera le même que le serveur, non?Pas pour le reflog. Le reflog est local sur le clone du référentiel.
@LeiYang Apprenez également à votre collègue que nous ne devrions jamais utiliser
--force
mais préférer--force-with-bail
pour éviter les perdu des commits (même si vous avez 100 jours, par défaut pour récupérer le commit dans lereflog
de tous les développeurs ayant tiré le commit supprimé).