Table des matières
Nous avons vu dans un précédent tutorial comment créer un repository de code Java dans Bitbucket, et comment connecter un projet Eclipse à ce repository. Nous avons vu notamment deux opérations fondamentales de Git : le push et le pull, qui permettent respectivement de pousser des modifications locales dans un repository distant, et de récupérer les modifications d'un repository distant avec un repository local.
Ce deuxième tutorial a pour but de montrer trois opérations supplémentaires : le fork, le clone (nous allons revoir cette opération) et le pull request.
La situation de départ est la suivante : une personne a créé un repository Git sur un serveur distant. Nous allons continuer avec l'exemple de Bitbucket, mais les opérations avec Github seraient exactement les mêmes, exposées dans des interfaces légèrement différentes toutefois.
Le contenu de ce repository nous intéresse. Cela peut être le cas si nous travaillons en équipe avec cette personne, ou si nous avons besoin de récupérer le code contenu dans ce repository pour travailler dessus. Peut-être s'agit-il d'un sujet d'examen ou de TP.
Nous allons donc voir ici comment dupliquer ce repository distant qui ne nous appartient pas dans un autre respository distant qui nous appartient. Une fois dupliqué ce repository, nous allons l'importer dans Eclipse, en deux temps.
Enfin, nous allons le modifier, et proposer au propriétaire du repository initial d'accepter cette modification.
Supposons que l'on parte de la situation suivante : un repository Bitbucket a été partagé avec nous en lecture. Ce repository s'appelle paddingOracleServer, il appartient à un utilisateur qui s'appelle Damien.
Le fait de partager un repository avec une personne déclenche l'envoi d'un mail, que nous avons reçu. Lorsque l'on se rend sur la page d'accueil de Bitbucket, ce repository apparaît avec les nôtres.
Si l'on clique sur ce repository et que l'on vérifie les droits que l'on a dessus, on se rend compte qu'effectivement, on n'y a accès qu'en lecture.
Il est donc évident que l'on ne peut modifier ce repository, en particulier, il nous est impossible d'y ajouter des commits, des branches, des tags, etc...
La première opération que nous allons faire consiste à dupliquer ce repository dans notre compte Bitbucket. Cette opération s'appelle fork. On peut forker un repository à partir de l'interface Web de Bitbucket comme dans la capture suivante.
Bitbucket nous propose d'enregistrer quelques détails sur ce fork.
Cette opération n'est pas instantanée, on a donc droit à une petite barre de progression.
Une fois l'opération menée à bien, seul le repository forké apparaît dans notre compte. En examinant les détails de ce repository, on se rend compte qu'il a gardé en mémoire le fait qu'il a été forké d'un repository original.
Notons que l'on peut forker n'importe quel repository Bitbucket, dès l'instant que l'on peut le lire. Il est donc aussi possible de forker tout repository public, de n'importe quel compte, sans avoir besoin d'y être invité.
Une fois ce repository forké, on veut pouvoir le modifier en local, dans Eclipse par exemple. Il faut commencer par le cloner : on recopie à l'identique un repository distant dans un repository local.
La première étape est, comme d'habitude, de copier l'URL de ce repository. Il y a plusieurs moyens d'obtenir cette URL, comme celui indiqué sur la capture suivante.
On passe ensuite dans Eclipse. On peut utiliser la vue Git repository d'Eclipse pour faire le clone, comme dans la capture suivante.
Dans cette vue se trouve un lien "Clone a Git repository", et c'est sur ce lien que nous allons cliquer. Eclipse nous ouvre alors un panneau dans lequel il nous faut indiquer l'URL de ce repository distant, ainsi que différentes informations classiques telles que login / mot de passe.
Une fois entrés ces détails et si le login / mot de passe est correct, Eclipse nous ouvre un deuxième panneau, nous demandant de préciser les branches que l'on veut rapatrier dans le repository local. Ici on sélectionne les deux branches master et solution.
Le panneau suivant est très important. Il nous permet de spécifier l'endroit sur notre disque local, où l'on veut enregistrer la copie du repository distant. On peut bien sûr choisir n'importe quel répertoire. Il est toutefois important de noter ce répertoire si l'on veut pouvoir le retrouver dans les étapes suivante.
En cliquant sur le bouton Browse... on peut naviguer vers un répertoire d'enregisrement. Ici on choisit simplement de créer un répertoire dans le workspace Eclipse dans lequel on se trouve. Cela nous permettra d'importer ce répertoire sous forme de projet Eclipse / Maven plus simplement.
Une fois ce répertoire choisi, la fenêtre d'import a cette allure.
Il ne nous reste plus qu'à cliquer sur le bouton Finish pour que l'import démarre. Après un certain temps, le repository cloné apparaît dans la fenêtre Git Repositories, sous la forme suivante.
On pourra remarquer que le repository d'où provient ce clone a été automatiquement enregistré en tant que repository "origin" dans ce repository local. Les opérations de push et de pull on été automatiquement créée également.
Une fois ce repository cloné en local, il nous faut encore l'importer en tant que projet Eclipse pour commencer à travailler avec.
Importé un projet cloné n'est pas très compliqué, mais peut-être un peu plus qu'il n'y paraît tout de même. Il faut comprendre qu'un projet Java peut être créé avec d'autres outils qu'Eclipse. Il existe trois IDE principaux dans la nature : Eclipse bien sûr, mais aussi Netbeans et Intellij IDEA. Ces trois IDE utilisent des fichiers propriétaires qui ne sont pas entièrement compatibles les uns avec les autres, et en tout cas pas du tout interchangeables. Un projet créé avec Netbeans ne peut pas être ouvert directement dans Eclipse, sans un peu de manipulations.
De ce fait, on n'enregistre en principe pas ces fichiers propriétaires dans un repository Git. Ce qui signifie que lorsque l'on télécharge un projet Java à partir d'un serveur tel que Bitbucket ou Github, on n'a en général pas les fichiers de configuration de l'IDE qui a servi à créer ce projet.
Cela n'est pas trop grave, puisque la plupart du temps, les projets Java
utilisent Maven, et que le fichier pom.xml
qui enregistre
dans ce cas la configuration du projet est systématiquement présent. Si
mettre les fichiers .classpath
ou .project
d'Eclipse dans Git est une mauvaise pratique, enregistrer le fichier
pom.xml
est, au contraire, une pratique indispensable.
La procédure d'import se déroule donc en deux temps. Tout d'abord nous allons importer ce repository en tant que projet Eclipse générique, et ensuite nous allons dire à Eclipse qu'il s'agit d'un projet Maven. Eclipse sait quoi faire avec un projet Maven, donc tout devrait bien se passer.
Commençons donc par importer ce repository en tant que projet Eclipse. On peut le faire avec le menu contextuel qui se trouve sur le nœud Working tree de notre repository, option Import Projects... Cette option se trouve dans d'autres menus contextuels également.
Le panneau suivant nous demande sous quelle forme nous voulons réaliser cet import. Nous choisissons la dernière option : Import as general project.
Le dernier panneau nous permet de valider ce qu'Eclipse va faire : importer le repository en tant que projet "paddingoracleclient" dans le répertoire de notre workspace Eclipse. C'est bien ce que l'on veut faire, on clique donc sur Finish.
L'import est à peu près instantané (ici tout se déroule en local), et le projet apparaît ensuite dans la vue Package Explorer d'Eclipse. Comme on peut le voir, il ne s'agit pas d'un projet Java (il n'y a pas le J en surimpression sur l'icône du projet), ce qui est normal, nous l'avons importé en tant que projet générique.
Comme il s'agit d'un projet Maven, la conversion en projet Java va
être particulièrement simple. Nous allons chercher la rubrique Configure
du menu contextuel du projet, et convertir ce projet en projet Maven.
Ceci n'est possible que si Eclipse a bien détecté la présence d'un
fichier pom.xml
dans notre projet.
Si tout se passe bien, notre projet doit apparaître sous cette forme dans notre vue Package Explorer.
Il est possible que Maven ait un peu de mal à tout importer du premier coup. Si notre projet apparaît avec un point d'exclamation rouge sur son icône, c'est qu'effectivement Maven a eu un hoquet.
Une solution simple et efficace consiste forcer la mise à jour du projet. Cela se passe dans le menu contextuel du projet : option Maven puis Update project...
Le panneau suivant apparaît, sur lequel il faut cocher la case Force update of snapshot / releases avant de cliquer sur le bouton Ok.
En principe cette procédure suffit à remettre la configuration en état.
On peut donc à présent travailler avec notre projet en local, le modifier, le faire évoluer. On peut également pousser nos modifications dans notre repository distant, dont nous sommes propriétaire.
Rappelons-nous toutefois que notre repository distant est en fait un fork d'un autre repository, que nous pouvons lire mais que nous ne pouvons pas modifier.
Supposons que l'on détecte un bug dans le code du repository que nous avons forké, et que l'on ait écrit un correctif pour ce bug. Nous ne pouvons pas enregistrer ce correctif dans le repository original, puisque nous ne pouvons pas le modifier. Mais nous pourrions avoir envie de proposer ce correctif à Damien, propriétaire du repository originel.
Git propose un mécanisme particulier pour ce faire, qui se trouve être très utilisé dans les communautés de développement Open source. Il s'agit du Pull request, souvent appelé PR. Nous ne pouvons pas faire de Push sur le repository original, car nous n'avons pas les droits pour le faire. Nous allons donc proposer Damien de faire un Pull de notre repository dans le sien. Damien ne peut pas non plus modifier le fork que nous avons fait de son repository, puisque ce fork est un repository qui nous appartient. Mais il peut le lire au travers du Pull request que nous lui proposons.
Commençons donc pas modifier le projet Java en local. Ouvrons pour cela
le fichier pom.xml
.
On peut améliorer ce fichier, en ajoutant une information sur l'encodage
des fichiers source de ce projet dans l'élément properties
.
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Le fichier POM modifié aura alors cette allure.
On peut alors commiter cette information en local, et la pousser vers notre repository Bitbucket.
Eclipse nous informe que le Push s'est bien déroulé.
Retournons alors sur l'interface de Bitbucket, afin de constater que le Push a bien été enregistré.
Parmi les boutons qui se trouvent dans la marge de gauche de l'interface Bitbucket, s'en trouve un qui nous permet de faire des Pull requests.
Bitbucket prépare le travail pour nous et nous présente un écran d'accueil pour cette fonctionnalité.
On passe ensuite à l'écran suivant, qui nous donne les détails de notre pull request.
On peut choisir la branche qui contient le code que l'on veut proposer à Damien, et la branche d'accueil.
On peut saisir un message d'explication, à la façon d'un mail.
Et la dernière information concerne les commits qui sont proposés à Damien, avec leurs messages. Ici nous n'avons qu'un seul commit, on pourrait bien sûr en avoir plusieurs. Á noter que l'onglet Diff nous permet de visualiser précisément le contenu de nos commits : les lignes ajoutées, modifiées et effacées.
Il ne nous reste plus qu'à cliquer sur Create Pull Request pour envoyer ce pull request à Damien.
On peut revoir les pull requests que l'on a envoyés. Damien pourra nous envoyer un message sous forme de commentaire, nous pourrons lui répondre, etc... Á la fin, il pourra ou non accepter notre pull request, et nous en serons notifié.
Notons que sur cette capture le pull request est bien dans l'état "open", ce qui signifie qu'il a été envoyé mais pas encore accepté.
Comme nous l'avons vu, un repository forké conserve la mémoire du repository d'où il vient. Lorsque l'on ouvre la page de détails de ce repository, on se rend compte que Bitbucket nous donne des informations en temps réel sur l'état du repository originel.
Sur la capture suivante, on se rend compte que le repository de Damien a évolué et que nous avons à présent 4 commits de retard. Bitbucket nous propose donc de synchroniser automatiquement notre repository avec celui de Damien, donc de forker également ces 4 commits.
On peut également aller visiter ce repository directement à partir du nôtre, en suivant le lien proposé dans l'interface (lien "Fork off").
On peut alors aller visiter les pull request adressées à ce repository (bouton dans la barre verticale de gauche), et à condition de filtrer sur les pull request dans l'état "merged", on se rend compte que Damien a accepté le nôtre.
En cliquant directement sur ce pull request, on accède à une page de détails, et l'on constate qu'effectivement ce pull request est dans l'état "Merged".
Bitbucket garde la trace de l'intégralité de l'activité sur les repositorys, y compris bien sûr les pull request externes.