1.7.3 Les push sur Repository

Bob est le premier à sauvegarder ses modifications sur Repository :

git push 
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 376 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To XXX/../Repository/Alice.git/
   01dbf03..ddf5337  master -> master

Jusque là, rien de bien compliqué, mais ça ne va pas durer.

Maintenant c'est Alice qui tente de faire une sauvegarde sur Repository :

git push 
To ../Repository/Alice.git/
 ! [rejected]        master -> master (fetch first)
error: impossible de pousser des références vers '../Repository/Alice.git/'
astuce: Les mises à jour ont été rejetées car la branche distante contient du travail que
astuce: vous n'avez pas en local. Ceci est généralement causé par un autre dépôt poussé
astuce: vers la même référence. Vous pourriez intégrer d'abord les changements distants
astuce: (par exemple 'git pull ...') avant de pousser à nouveau.
astuce: Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus d'information.

Aïe, aïe, aïe, ça ne pouvait pas duré, mais encore une fois, git nous donne une astuce pour régler le problème.

Il nous propose de faire un git pull suivit d'un git commit -a puis d'un git push.

git pull 
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
Depuis ../Repository/Alice
   01dbf03..ddf5337  master     -> origin/master
Fusion automatique de main.cpp
CONFLIT (contenu) : Conflit de fusion dans main.cpp
La fusion automatique a échoué ; réglez les conflits et validez le résultat.

Ah, voilà tout le problème de développer sur les mêmes fichiers à plusieurs, si j'ai un conseil à vous donner, c'est de toujours séparer les fichiers par utilisateurs, ou de créer des branches (mais on verra ça plus tard).

Mais cela ne veut pas dire que git pull n'a rien fait, il a en fait fusionner les deux modifications.

Voici le nouveau fichier main.cpp :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <iostream>

using namespace std;

///fonction qui écrit en bleu
/**	@param str : chaîne de caractères à écrire en bleu
*/
void printBleu(const char * str){
	printf("\033[34m%s\033[0m\n", str);
}

<<<<<<< HEAD
///fonction qui écrit en jaune
/**	@param str : chaîne de caractères à écrire en jaune
*/
void printJaune(const char * str){
	printf("\033[33m%s\033[0m\n", str);
=======
///fonction qui écrit en violet
/**	@param str : chaîne de caractères à écrire en violet
*/
void printViolet(const char * str){
	printf("\033[35m%s\033[0m\n", str);
>>>>>>> ddf53371bacb7e137a818d05c11fdcabff177ab2
}

int main(int argc, char** argv){
	cout << "Super projet à sauvegarder" << endl;
	printBleu("Truc en bleu");
<<<<<<< HEAD
	printJaune("Truc en jaune");
=======
	printViolet("Truc en violet");
>>>>>>> ddf53371bacb7e137a818d05c11fdcabff177ab2
	return 0;
}

Il faut reconnaître que sur le coup, ça à l'air désordonné, mais c'est bien ranger, au contraire. Je vous laisse quand même imaginer la tête d'un fichier de plusieurs millier de ligne, quand vous avez des modifications un peut partout.

1
2
3
4
5
<<<<<<< HEAD
Modification sur le dépos courant (Ici Alice)
=======
Modification sur le dépos distant (Ici Repository)
>>>>>>> XXXXXX

Si on fait un git status :

git status 
Sur la branche master
Votre branche et 'origin/master' ont divergé,
et ont 1 et 1 commit différent chacune respectivement.
  (utilisez "git pull" pour fusionner la branche distante dans la vôtre)

Vous avez des chemins non fusionnés.
  (réglez les conflits puis lancez "git commit")

Chemins non fusionnés :
  (utilisez "git add ..." pour marquer comme résolu)

	modifié des deux côtés :main.cpp

aucune modification n'a été ajoutée à la validation (utilisez "git add" ou "git commit -a")

L'explication de git a le mérite d'être clair. Le fichier main.cpp a été modifié depuis deux dépos différents. En fait il vérifie si il y a des délimiteurs <<<<<<< HEAD, ======= et >>>>>>> XXXXXX, et si il en trouve il sait que le fichier à été modifier par N dépos différents.

Il ne manque pas une accolade ?

Il manque une accolade fermante, mais c'est normale car dans les deux cas elle est à la ligne 18 du fichier main.cpp, que ce soit pour le dépos d'Alice ou celui de Bob.

Voici le nouveau fichier main.cpp une fois que les conflits ont été réglés par Alice :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <iostream>

using namespace std;

///fonction qui écrit en bleu
/**	@param str : chaîne de caractères à écrire en bleu
*/
void printBleu(const char * str){
	printf("\033[34m%s\033[0m\n", str);
}

///fonction qui écrit en jaune
/**	@param str : chaîne de caractères à écrire en jaune
*/
void printJaune(const char * str){
	printf("\033[33m%s\033[0m\n", str);
}

///fonction qui écrit en violet
/**	@param str : chaîne de caractères à écrire en violet
*/
void printViolet(const char * str){
	printf("\033[35m%s\033[0m\n", str);
}

int main(int argc, char** argv){
	cout << "Super projet à sauvegarder" << endl;
	printBleu("Truc en bleu");
	printJaune("Truc en jaune");
	printViolet("Truc en violet");
	return 0;
}

Comme nous avons réglé les conflits nous pouvons sauvegarder les changements.

Ne tentez pas de faire un git commit -a si nous n'avez pas réglé les conflits car git ne vous laissera pas faire.

git status 
Sur la branche master
Votre branche et 'origin/master' ont divergé,
et ont 1 et 1 commit différent chacune respectivement.
  (utilisez "git pull" pour fusionner la branche distante dans la vôtre)

Vous avez des chemins non fusionnés.
  (réglez les conflits puis lancez "git commit")

Chemins non fusionnés :
  (utilisez "git add ..." pour marquer comme résolu)

	modifié des deux côtés :main.cpp

aucune modification n'a été ajoutée à la validation (utilisez "git add" ou "git commit -a")

On sauvegarde tout les changements :

git commit -a -m "ajout d'une fonction qui affiche un texte en jaune et résolution des conflits entre les dépos"
[master c91301d] ajout d'une fonction qui affiche un texte en jaune et résolution des conflits entre les dépos

On envoie le tout sur le dépos Repository :

git push 
Counting objects: 10, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 687 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To ../Repository/Alice.git/
   ddf5337..c91301d  master -> master

Maintenant Bob peut se synchroniser avec le dépos Repository :

cd ../Bob/Alice/
remote: Counting objects: 10, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
Depuis /home/pierre/Documents/PROGRAMMATION/C++/CONSOLE/TEST_GIT_2_utilisateurs/Bob/../Repository/Alice
   ddf5337..c91301d  master     -> origin/master
Mise à jour ddf5337..c91301d
Fast-forward
 main.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

Bob a récupérer le nouveau main.cpp :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <iostream>

using namespace std;

///fonction qui écrit en bleu
/**	@param str : chaîne de caractères à écrire en bleu
*/
void printBleu(const char * str){
	printf("\033[34m%s\033[0m\n", str);
}

///fonction qui écrit en jaune
/**	@param str : chaîne de caractères à écrire en jaune
*/
void printJaune(const char * str){
	printf("\033[33m%s\033[0m\n", str);
}

///fonction qui écrit en violet
/**	@param str : chaîne de caractères à écrire en violet
*/
void printViolet(const char * str){
	printf("\033[35m%s\033[0m\n", str);
}

int main(int argc, char** argv){
	cout << "Super projet à sauvegarder" << endl;
	printBleu("Truc en bleu");
	printJaune("Truc en jaune");
	printViolet("Truc en violet");
	return 0;
}

C'était un peu laborieux, mais on a toujours des problèmes quand on modifie le même fichier à plusieurs.