Actions

Cours

Versioning avec Git

De GBLL, TAL, ALAO, etc.

Il existe pléthore de tutoriels sur Git[1], cette page ne se donc pas pour objectif de présenter le logiciel en profondeur, mais seulement de le présenter brièvement et centraliser quelques liens utiles pour télécharger, utiliser et comprendre Git.

Langfr-1920px-Git-logo.svg.png

En bref

Git est un logiciel de gestion de versions décentralisé. C'est un logiciel libre créé par Linus Torvalds, auteur du noyau Linux, et distribué selon les termes de la licence publique générale GNU version 2. En 2016, il s’agit du logiciel de gestion de versions le plus populaire qui est utilisé par plus de douze millions de personnes. (source:[1])

En gros, Git vous permet de tenir un historique de toutes les modifications que vous faites dans votre code, et permet de revenir facilement en arrière si besoin. De plus, si vous travaillez en équipe, vous pouvez utiliser un hébergement distant (comme Github ou GitLab) pour travailler avec un historique commun, sauvegarder votre code, et gérer facilement les conflits de fusion lorsque deux développeurs mettent en ligne des modifications différentes du même élément.

Rien de mieux qu'un petit tuto vidéo pour comprendre les bases. En voici un avec l'accent du Sud-Ouest.

Git vous permet également de créer des branches de travail dans votre projet. Par exemple, imaginons que vous avez développé un logiciel. Un jour, vous souhaitez implémenter de nouvelles fonctionnalités, mais pour éviter de tout chambouler dans votre code qui marche, vous pouvez créer une nouvelle branche, y faire tout ce que vous avez à faire, et si vous êtes satisfaits, vous la fusionnerez ensuite avec la branche principale de votre projet (master).

Principe des branches sur Git

En général, la branche principale (master) est réservée pour le code fonctionnel, la vitrine de votre projet. Toutes les fonctionnalités de votre programme sont développées sur des branches de développement, puis fusionnées régulièrement avec la branche principale.

Exemple d'utilisation avancée des branches

Installation

Pour Windows, je vous conseille d'installer Git Bash. Pour Linux vous l'avez déjà en principe[2]. Pour Mac (ou Windows) rendez-vous sur ce site pour télécharger la version qui vous intéresse.

Configuration

Une fois que git est installé, la première chose à faire est de lui donner votre identité pour que toutes vos contributions vous soient associées (sinon il ne vous laissera pas faire de commit).

git config --global user.email "pierre@paul.fr" #renseigner son email de contact (si vous ne l'avez jamais fait);
git config --global user.name "Jacques" #renseigner son nom ;
git config --global color.ui true #active la coloration syntaxique de Git (c'est plus sympa) ;
git config --list #liste la configuration de Git ;

Chaque dépôt peut avoir une configuration spécifique qui prend le pas sur la configuration globale (il suffit de remplacer --global par --local dans les commandes ci-dessus[3].

Gestion des mots de passe (Linux[4])

Tous les dépôts distants n'utilisent pas ssh. Pour ceux-là, il peut être pratique de laisser git retenir vos mots de passe. Pour une fois Windows, le fait out-of-the-box, alors que Linux vous demande de faire un choix[5]

Le plus simple est d'utiliser libsecret :

sudo apt-get install libsecret-1-0 libsecret-1-dev
cd /usr/share/doc/git/contrib/credential/libsecret
sudo make
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

Commandes de base au terminal

Pour ouvrir un terminal :

  • WINDOWS avec Git Bash : Dans le dossier de votre choix, clic droit puis Git Bash Here ;
  • WINDOWS avec terminal DOS : windows+r puis entrez "cmd", vous pouvez aussi utiliser un logiciel comme PowerShell ;
  • Linux : ctrl+alt+t, ou dans un dossier clic droit puis ouvrir dans un terminal ;
  • Mac : entrez "terminal" dans le dock.

Navigation basique dans le système de fichiers (en Bash) :

  • cd chemin/du/dossier, pour se déplacer vers un dossier ;
  • ls, pour lister les fichiers et dossiers ;
  • mkdir nomDuDossier, créer un nouveau dossier ;
  • cp chemin/du/fichier nouveau/chemin, copier un fichier d'un point A à un point B ;
  • rm fichier, supprimer un fichier (ne passe pas par la corbeille!).

Commandes Git de base :

  • git init, initialiser Git dans un nouveau dossier ;
  • git add ., ajoute toutes les dernières modifs pour commit ;
  • git commit -m "Description des modifications", commit les modifications ;
  • git status, permet de savoir quelles modifications sont en attentes d'être commit ;
  • git log, affiche la liste des derniers commits ;
  • git log --oneline, pareil mais chaque commit sur une ligne ;
  • git reflog, historique facile à lire des dernières opérations (commits, checkouts etc.) ;
  • git log -S "coucou les amis", cherche les commits où j'ai modifié la/les ligne(s) qui contiennent "coucou les amis";
  • git stash, vous permet de mettre de côté toutes les modifs en cours et revenir à l'état du dernier commit, ça vous permet de faire une correction de bug en urgence par exemple, puis committer et pusher, et ensuite vous pouvez réafficher vos modifications en cours avec git stash pop et continuer votre travail.

Commandes de mise à jour avec le dépôt distant

  • git clone AdresseProjetGitDistant, clone un projet git distant sur votre ordinateur ;
    • Exemple: git clone git@gricad-gitlab.univ-grenoble-alpes.fr:coulangs/site-web.git.
  • git pull, récupère les dernières modif enregistrées sur le git distant et met à jour votre projet local ;
  • git push, envoie les dernières modif locales vers le git distant pour le mettre à jour;

De manière générale, avant de pusher vers le dépôt distant, faites toujours un pull pour vous assurer qu'il n'y a pas eu de modifications sur GitLab depuis votre dernier pull. Cela permet de mettre à jour votre projet local et faire les fusions nécessaires le cas échéant, avant d'envoyer vos nouvelles modifications vers GitLab.

→ Faire un nouveau commit et le pusher immédiatement sur GitLab revient à faire les commandes :
git add ., git commit -m "description du commit", git pull, et git push.

  • La commande git commit -a -m "description du commit" est un raccourci pour git add . + git commit -m "description du commit"
  • Lorsque vous pullez, si il y a des modifications sur GitLab que vous n'avez pas en local, Git s'occupe de fusionner les deux versions.
    • Si il y a un conflit, faites git status pour savoir de quels fichiers il s'agit, puis modifiez les fichiers comme vous le souhaitez.
    • S'il y a une fusion sans conflit, un message de fusion peut s'afficher : vous pouvez simplement faire ctrl+X pour sortir. Tout va bien, vous pouvez pusher.

Gérer un conflit

Si quelqu'un a modifié la même ligne d'un fichier que vous avant que vous ayez pushé sur le dépôt distant, il peut y avoir un conflit. Cela veut simplement dire que 2 modifications différentes portent sur la/les mêmes lignes, et que Git seul ne peut pas choisir ce qu'il doit garder. Dans ce cas, il revient à la personne chez qui le conflit arrive (le dernier des deux qui push) de choisir quelle(s) modification(s) garder. Pour cela, commencez par faire un git status pour savoir sur quel(s) fichier(s) il y a un conflit, ensuite, ouvrez ces fichiers dans votre éditeur, et vous trouverez les lignes concernées par le conflits entre <<<<<<<<< et >>>>>>>>>. Il suffit de supprimer les parties que vous ne souhaitez pas garder (les <<<<<<<<< et >>>>>>>>> inclus), puis enregistrer, committer, puller et pusher.

Des outils sont disponibles pour vous aider à résoudre les conflits. Par exemple, Atom embarque cette fonctionnalité. Vous pouvez également configurer un outil externe, comme meld.

Commandes relatives aux branches

Par défaut, vos commit sont enregistrés sur la branche principale de votre historique (master). Vous pouvez créer de nouvelles branches pour effectuer des tests, développer de nouvelles fonctionnalités, en évitant de modifier (de saccager?) master. Si vous êtes satisfait, vous pouvez ensuite fusionner master avec la nouvelle branche, ou simplement continuer à committer sur votre nouvelle branche.

  • git branch, lister les branches existantes ;
  • git branch nomBranche, créer une nouvelle branche appelée "nomBranche" ;
  • git checkout nomBranche, se déplacer vers la branche nomBranche ;
  • git checkout master, se déplacer vers la branche "master" ;
  • git merge nomBranche, fusionne la branche courante à la branche nomBranche ;
  • git branch -D nomBranche, supprime la branche nomBranche.


Chaque branche possède son propre historique. Les commandes push/pull ne s'appliquent que pour la branche sur laquelle vous êtes. Si vous créez une nouvelle branche, vous pouvez la pusher sur votre dépôt distant (git push -u origin nomBranche), ou bien la garder seulement en local.

Pour revenir en arrière :

Annuler le dernier commit

  • git revert HEAD, crée un nouveau commit qui repasse le projet à l'état précédant le dernier commit (HEAD). Rien n'est perdu, on peut toujours revenir à l'état du dernier commit (en refaisant la même chose). C'est le meilleur moyen de revenir en arrière;
  • git revert <clé_du_commit> permet d'annuler les modifications apportées par le commit <clé_du_commit>.

Voir l'état de votre projet à un instant t dans votre historique

  • git checkout <clé_du_commit>, vous permet de voir l'état du projet lors du commit <clé_du_commit>
    • pour revenir au présent, faites git checkout master;
    • Vous pouvez aussi voir l'état d'un seul fichier lors d'un certain commit : git checkout <clé_du_commit> nomDuFichier.


Lorsque vous allez voir dans le passé avec cette méthode, vous vous retrouvez dans un état de "HEAD détachée". C'est comme un instant fictif dans votre historique. À partir de là, soit vous revenez dans le présent (git checkout master), soit vous créez une nouvelle branche (git branch nomNouvelleBranch puis git checkout nomNouvelleBranch) et vous committez dessus. Ça vous permettra de repartir de cet instant, et de continuer à committer normalement au fur et à mesure de vos modifications. Votre historique sur master s'arrête là, mais il est toujours disponible si besoin.

Supprimer complètement un commit

Attention, ici vous supprimer des bouts d'historique, donc pas de retour en arrière possible. Ça peut servir si vous committez un gros fichier puis que vous souhaitez le supprimer de votre historique parce qu'il est trop lourd.

  • git reset <clé_du_commit> --hard, supprime tous les commits depuis <clé_du_commit> et revient à l'état du projet de l'époque.

Note : Si vous supprimez des bouts d'historique avec reset, et que vous remontez dans le temps par rapport à l'état du projet sur votre dépôt distant, il est nécessaire que le propriétaire du projet autorise la suppression de données dans l'historique du dépôt.

Remote Git

Il existe plusieurs services vous permettant de tenir un journal de gestions de versions de votre code. Le plus connu est probablement GitHub. Nous utiliserons dans ce cours le service Gricad-GitLab de l'UGA. Le fonctionnement est très similaire à celui de GitHub, ou d'autres services comme Bitbucket.

Cas: Vous avez créé un projet en local et souhaitez le pusher pour la première fois sur GitLab

  • Rdv sur Gricad-GitLab;
  • Connectez-vous avec vos identifiants universitaires;
  • Si vous ne l'avez pas déjà fait, renseignez votre clé publique dans User Settings > SSH Keys (voir cas ci-dessous);
  • Créez un nouveau projet, décrivez-le brièvement, choisissez le degré de visibilité;
  • GitLab vous propose déjà des options pour pusher un dossier existant que vous avez en local, il suffit de copier-coller la commande git remote add origin git@gricad-gitlab.univ-grenoble-alpes.fr:votreIdentifiant/votreProjet.git et l'exécuter en local, dans votre dossier de projet (à faire une fois que vous avez initialisé git dans ce répertoire!);
  • ensuite faites au moins un commit (git add . puis git commit -m "votre message"), puis votre premier push avec la commande git push --set-upstream origin master. Ensuite, pour pusher vers master, il suffira d'exécuter git push.
  • puis rafraîchissez votre page sur GitLab, et vous devez voir apparaître vos fichiers.

Cas: Vous souhaitez renseigner votre clé publique sur GitLab

  • Tout d'abord vous devez récupérer votre clé rsa :
    - Sur Windows et Mac, si vous voulez utiliser un logiciel graphique dédié, utilisez PuttyGen et suivez ce tutoriel;
    - Sinon et pour tout le monde, lancez Git Bash n'importe où, puis tapez la commande cd qui vous positionnera dans votre "home";
    - Vérifiez si vous avez déjà une clé : cd .ssh, si le dossier existe, les clés sont dedans (id_rsa.pub pour la clé publique);
    - si le dossier .ssh n'existe pas, vous n'avez pas de clé, dans ce cas on va générer une paire : ssh-keygen, puis "entrer" pour l'enregistrer dans la destination par défaut, vous pouvez éventuellement indiquer un mot de passe (passphrase);
    - maintenant allez dans le dossier .ssh (cd .ssh), puis listes les fichiers (ls), vous devez voir votre clé privée (id_rsa, à ne pas toucher ni transmettre) et votre clé publique (id_rsa.pub, c'est elle que vous devez utiliser pour vous connecter à un serveur (dont GitLab) de manière sécurisée;
    - affichez le contenu de la clé publique (cat id_rsa.pub, ou ouvrez-le dans un bloc-note par exemple) et copiez-la pour la coller dans GitLab.
  • Rdv sur Gricad-GitLab;
  • Connectez-vous avec vos identifiants universitaires;
  • Allez dans User Settings > SSH Keys, puis collez votre clé publique et validez.

Cas: Vous souhaitez télécharger un projet depuis GitLab sur votre PC

  • Allez sur la page du projet qui vous intéresse sur GitLab, par exemple celle que j'ai créée en cours;
  • Cliquez sur le bouton Clone puis copiez l'adresse de Clone with SSH;
  • En local, sur votre machine, ouvrez Git Bash là où vous souhaitez télécharger le projet, puis tapez git clone git@gricad-gitlab.univ-grenoble-alpes.fr:coulangs/nouveau-projet.git. Si votre projet est public (comme celui-ci), n'importe qui peut le voir et le cloner. Pour pusher dessus par contre il faut que le propriétaire du projet ajoute des collaborateurs dans les paramètres (Members);
  • Pour vérifier que le clonage à fonctionné, allez dans le dossier du projet fraîchement cloné, puis git log pour voir la liste des commits qui devrait apparaître.

Notes et références

  1. Sur ce wiki, le cours génie logiciel et gestion de versions
  2. Sinon sudo apt-get install git
  3. Comme --local est le comportement par défaut, vous pourriez vous contenter d'utiliser la commande sans --global
  4. Debian, Ubuntu et dérivés
  5. https://www.softwaredeveloper.blog/git-credential-storage-libsecret
    https://crates.io/crates/git-credential-keepassxc
    etc.