Comment git fonctionne quand deux pairs poussent simultanément les modifications vers la même télécommande

Je suis nouveau sur git, j’utilise généralement P4 qui a un repository central, alors que git est dissortingbué VCS.

Je suis intéressé par le fonctionnement de git lorsque deux pairs poussent simultanément les modifications vers la même télécommande. Supposons que chaque pair a résolu tous les conflits avant de pousser. Je suppose que le dernier sera rejeté si git rapporte des conflits!

Cependant, d’après ce que j’ai compris, git est en interne un magasin de clés / valeurs, tout comme la firebase database NOSQL actuelle, en particulier Couch-DB, qui prend en charge la réplication p2p.

En fait, je veux demander comment git process conflit dans le cas où les clients poussent les modifications vers le référentiel git distant? La poussée est-elle rejetée?

De la réponse de Mark, je pense que la poussée devrait être rejetée.

Réponse courte

Oui, l’une des poussées sera rejetée, peu importe celle qui est postérieure, même si c’est juste une microseconde, comme le mentionne Jefromi dans son commentaire. Cependant, il sera rejeté car le référentiel distant voit que l’historique de la poussée ultérieure n’inclut pas l’historique du précédent, car il ne détecte aucun conflit dans le contenu qui est envoyé.

Réponse plus détaillée

Habituellement, une poussée sera rejetée si elle ne “accélère” pas la twig, dans la terminologie Git. Cela signifie que si votre maître est à A et que le référentiel distant est à B, alors le push ne réussira que si B est un ancêtre de A. (Je dis “généralement” car vous pouvez append des options pour “forcer” le push si le le référentiel distant le permet, mais ce n’est pas le cas typique.)

Dans le cas que vous décrivez, en supposant que les trois référentiels ont initialement la même histoire:

P -- Q -- R 

Et vous avez ajouté un commit S:

 P -- Q -- R -- S 

… alors que quelqu’un d’autre a ajouté un commit T:

 P -- Q -- R -- T 

Si cette autre personne est la première à pousser (c’est-à-dire que Git sur le serveur s’occupe d’abord de la diffusion), alors son push sera accepté car R est un ancêtre de T , alors le référentiel distant aura également l’historique P -- Q -- R -- T Si vous essayez par la suite de pousser, vous obtiendrez une erreur car T n’est pas un ancêtre de S En général, en voyant cela ! [rejected] ! [rejected] erreur, vous exécuterez git pull ou git pull --rebase pour vous assurer que vous êtes en avance sur master dans le référentiel distant.

git pull créera un commit de fusion M pour que votre historique ressemble à:

 P -- Q -- R -- T -- M \ / -- S - 

… tandis que git pull --rebase réappliquera les modifications que vous avez introduites au-dessus de T pour créer un nouvel commit, S' :

 P -- Q -- R -- T -- S' 

Dans l’un ou l’autre de ces cas, vous devriez être capable de pousser à nouveau, car T est un ancêtre de M et de S' . (Cela suppose que personne d’autre n’a repoussé dans l’intervalle!)

En n’autorisant que des raccourcis rapides, il n’y a jamais de résolution de conflits à distance – en cas de conflit, vous serez invité à les résoudre localement lorsque vous exécuterez git pull .

Il peut être intéressant de noter que la mise à jour appliquée au repository distant en réponse à un push est atomique. Dans l’exemple que nous avons décrit ci-dessus, où S et T sont poussés simultanément, ce sera toujours le cas. l’un d’eux est complètement appliqué tandis que l’autre échouera, sans effet.

Une note sur votre point clé / valeur

Alors que la firebase database d’objects de Git est implémentée comme un magasin de clés / valeurs, qui mappe les noms d’object (aussi appelés hashs ou SHA1sums) au contenu des objects, ils entendent «c’est comme un magasin de valeur clé» – il semble que cela puisse se produire dans votre cas, alors je suggère que penser à Git à ce niveau n’est pas l’approche la plus utile pour comprendre ce problème.