title: "Forks"
Imaginons que Julien propose un dépôt public, visible par tout le monde, mais
non modifiable (pour éviter que n'importe qui y fasse n'importe quoi). Si
Fabien (à qui il arrive parfois de faire n'importe quoi) veut proposer une
modification, il peut alors copier (forker) le dépôt de Julien, faire ses
modifications dans son dépôt, puis les soumettre à Julien (pull request), qui
choisira ou non de les intégrer dans le dépôt initial (upstream
).
Le fork est un mode de fonctionnement très répandu dans le monde de l'open-source (Github entre autres). Le serveur Gogs de l'université possède également une partie publique propice aux forks (cette partie publique est cependant réservée aux personnes identifiées à l'université).
Remarque : pour les intervenants réguliers et de confiance, il est plus simple de les autoriser à modifier directement le dépôt principal, en les ajoutant comme collaborateurs. Les deux systèmes (forks et collaboration) sont complémentaires.
Le dépôt de Julien est déjà sur le serveur, dans la partie publique. Fabien se connecte sur le site Gogs de l'université.
Il explore la zone publique et sélectionne le dépôt de Julien.
Il demande de forker le projet.
Ce qui lui crée un nouveau dépôt...
... qui est une copie du dépôt initial.
Fabien peut ensuite cloner son nouveau dépôt...
... y faire ses modifications (si possible dans une nouvelle branche), ...
... et les pusher sur son dépôt distant.
Un pull request permet de demander d'intégrer d'une modification d'un dépôt
forké dans le dépôt initial (upstream
).
Jusqu'ici, Fabien a forké le dépôt de Julien et fait des modifications sur son dépôt forké. Pour soumettre ses modifications, il va sur la page correspondant à son dépôt et clique sur le bouton pull request.
Il met un message pour Julien, expliquant ses modifications (ou pas d'ailleurs).
Le pull request est alors enregistré.
De son côté, Julien reçoit le pull request de Fabien, pour le dépôt initial.
Il peut alors regarder les modifications proposées, échanger des messages avec Fabien puis finalement accepter (ou refuser) les modifications.
Si le pull request est accepté, la modification est fusionnée dans le dépôt.
Elle apparait alors dans la liste des commits.
Si les modifications du fork ont été faites dans une nouvelle branche, il ne
faut pas oublier de la fusionner dans le master
, sur le dépôt upstream
.
En cas de conflit, le pull request doit être intégré manuellement (voir ci-dessous).
Après un fork, les deux dépôts (fork et upstream) peuvent évoluer
indépendamment. Pour récupérer les nouvelles modifications du dépôt initial
dans le dépôt forké, il suffit de l'ajouter comme dépôt distant (généralement,
on utilise le nom upstream
).
Par exemple, Fabien peut ajouter le dépôt initial (de Julien) sous le nom
upstream
avec la commande suivante (normalement, c'est déjà fait
grâce au fork).
git remote add upstream https://gogs.univ-littoral.fr/jdehos/tutoriel_git
On peut ensuite récupérer les évolutions du dépôt upstream
et les fusionner
dans le dépôt forké :
git fetch upstream
git merge upstream/master
Cette gestion des dépôts distants est très puissante. Elle permet, par exemple, de créer, pour un même projet, un dépôt distant public et un dépôt distant privé (éventuellement sur des serveurs différents) et de les synchroniser.
Autre exemple, Julien peut gérer manuellement un pull request de Fabien dans
une branche spéciale. Pour cela, il lui suffit d'ajouter et de récupérer le
dépôt distant de Fabien (par exemple sous le nom "fork_fabien") et de créer une
branche ("pull_request_fabien") pour y merger le master
de fork_fabien.
git remote add fork_fabien https://gogs.univ-littoral.fr/fteytaud/tutoriel_git
git fetch fork_fabien
git branch pull_request_fabien
git checkout pull_request_fabien
git merge fork_fabien/master
Résumé des commandes Git précédentes :
---|---|
git remote add <nom> <url>
| ajoute un dépôt distant |
git fetch <nom>
| récupère les commits d'un dépôt distant |
Quelques conseils de méthode de travail :
master
et pushez-la sur le dépôt distant privé et sur le dépôt distant
public.master
, fusionnez-le dans la branche
"public" et pushez le tout.