Git

git versioning

Comment cloner sans mot de passe un Repo Github

Support for password authentication was removed on August 13, 2021

Depuis cette date, il est impossible de cloner un repository privé, car pour cloner un repository privé il faut s’authentifier. Pour remplacer le mot de passe, Github utilise le PAT : Personal Access Token.

Comment créer le PAT avec Github

Pour créer le PAT, allez dans Settings sur la page d’accueil de votre Github, puis sur la barre latérale gauche, cliquer sur Developer Settings, puis sur Personal Access tokens, puis dans la liste choisissez Tokens (Classic)

Cliquez sur Generate new token dans la liste déroulante et choisissez classic.

Pour les opération usuelles, cliquez la checkbox repo, et choisissez une durée de validité, 30 jours par défaut. Une fois généré, copiez la chaine PAT en lieu sûr; car vous ne le verrez plus dans votre Github. (Evitez de le mettre dans votre repository !!!)

Comment utiliser le PAT pour cloner?

Le PAT remplace en lieu et place votre mot de passe, il est plus long et plus secret, et a une durée de vie déterminée, contrairement à votre mot de passe, il est donc plus sûr.

Donc suite à la commande git clone https://…

Username for 'https://github.com': votre_nick
Password for 'https://votre_nick@github.com

Au moment d’entrer le password, vous collez simplement votre PAT (Personal Access Token)

Ou alors si vous renseignez votre PAT ça va plus vite:

git clone https://<PAT>@github.com/<nick>/<repo>.git

Le PAT vous permet aussi d’utiliser le webservice de Github.

Utiliser le webservice de Github pour extraire des informations

Récemment, pour un projet open source, j’ai voulu afficher un classement des contributeur en fonction du nombre de commits. J’ai tout de suite eu l’idée de passer par le webservice de Github (alors que je n’en ai jamais entendu parler).

Il est normal que Github ait un webservice, cela permet de faire des nitégration un peut partout (plugin git par exemple).

Comment mener sa réflexion du webservice à l’affichage des badges pour récompenser les contributeurs?

L’idée de base est de proposer un classement des contributeurs en fonction du nombre de pull requests. Pour avoir les pull request, il faut avoir les commits sur la branch principale (dans notre cas develop).

Il a fallut d’abord trouver un moyen via la documentation de lister les commits d’une branche. Deplus j’ai pris le parti d’utiliser un token pour avoir moins de restriction sur les appels.

Exemple d’appel sans avoir besoin de clé:

https://api.github.com/user/repos

Appel avec un clé

Il faut d’abord générer une clé, plus exactement un PAT (personal Access Token). Pour ce faire aller à Settings, puis dans la barre de gauche aller dans Developper…

Générer le PAT, sélectionner les droits de ce PAT, je n’ai besoin qu’en lecture, donc cocher comme dans l’image. Je vous propose dans un premier temps d’expérimenter avec Postman, pour ceux qui ne le connaissent pas encore, Postman permet de faire des requêtes HTTP sans navigateur, pratique pour tester des webservices.

Vous aurez les repository du propriétaqire de votre token. Maintenant listons les commits d’une branches, il a fallu explorer la documentation, ne la baclez pas, la documentation est riche.

// lister les branches
https://api.github.com/repos/refschool/Clone-Weetransfert/branches

// lister les commits de la branche main
https://api.github.com/repos/refschool/Clone-Weetransfert/branches/main

//  lister les commits de la branche par défaut qui est main
https://api.github.com/repos/refschool/Clone-Weetransfert/commits

//  lister les commits de la branche develop avec 100 résultats par page.
https://api.github.com/repos/refschool/Clone-Weetransfert/commits?per_page=100&sha=develop

Il faut essayer de se familiariser avec la pagination le jour où l’on a vraiment beaucoup de commit.

Lien vers la documentation:

https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28

Mais ne peut on pas lister les pull request?

A l’évidence si ! voici la documentation :

https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#list-pull-requests

vous devez être le propriétaire du repo pour avoir les pull requests du projet (normal)

Défaire une action dans Git

Parfois on peut se tromper dans Git ! Il est donc utile de savoir comment annuler une action (en ligne de commande c’est mieux)

Défaire une modification de fichier non ajouté dans le staging area

git checkout -- nomfichier

Défaire un add

git reset fichier

Défaire un commit

# défaire le dernier commit
git reset --soft HEAD~1
# on revient à l'état où les fichiers sont ajoutés au staging area

$git reser --hard HEAD~1
#on revient à l'état où les fichiers sont non ajoutés au staging area

Défaire un commit qui été poussé

Ne plus trackere un fichier et l’ignorer du versioning

git rm --cached fichier

Vous aimeriez aussi savoir comment pusher sans mot de passe

Git cherry-pick sélectionner un commit d’une autre branche

Je vous présente une commande assez peu utilisée, considérée par certain comme une pas bonne pratique. J’ai u l’utiliser dans une situation bien particulière, en effet j’étais sur develop et j’ai fait une modif dans une autre branche on va dire une feature, que j’aurais dû faire sur develop. Ok on n’est pas sensé bosser sur develop en direct !

Mais c’est un projet où j’étais tout seul, donc je me permettais quelques arrangements.

Branch bleu (develop), branche rouge (feature), je prend le commit ‘taux valeur admin OK’

Je me place dans la branche de destination, develop donc en faisant un git checkout develop

Ensuite je repère le hash du commit de la branche feature, et je fait :

$ git cherry-pick hashDuCommit

Le résultat est le suivant :

On voit que develop a maintenant le commit avec le message ‘taux valeur admin ok’

N’utilisez le cherry-pick qu’avec parcimonie, je pense que si c’est mal fait, vous risquer de mettre votre git dans un sale état.

Vous aimeriez aussi savori comment mettre des commentaires multilignes dans vos commit

git versioning

Résoudre les conflits avec git en ligne de commande

Il est possible de merger une branche sans avoir besoin de résoudre les conflits si vous êtes sûr que la version qui va venir est la bonne.

Cas d’un merge depuis une branche

Par exemple vous avez une branche feature/login par exemple, que vous voulez merger dans develop, or vous savez que les fichiers de cette branche feature doit être la plus récente, dans ce cas la commande est la suivante :

git checkout develop
git merge -X theirs feature/login

Cas d’un pull depuis un repository

Maintenant vous êtes en train de faire un pull depuis le repository, dans ce cas les fichiers qui vont venir vont fusionner avec vos fichiers en local, par exemple, vous fait un git pull

git pull -X theirs

Mais que se passe-t-il si vous avez fait un simple git pull et que vous êtes en situation de conflit? Il est toujours possible de résoudre rapidement en favorisant ce qui vient:

git checkout --theirs .
git add .
#dans le cas où vous voulez privilégier votre version
git chekout --ours .
git add .
logo git

A quoi sert Git tag?

Git tag sert en général à marquer un version de release majeure. Par exemple lorsque votre logiciel passe à la version 2.0.0 ou à la version 1.5.0, voire 1.5.4 quoique.

Comme d’habitude avec Git, chaque commande fait beaucoup de choses, mais nous pouvons voir les choses de façon plus simple (point de vue adopté ici), c’est comment utiliser les commandes de Git pour notre travail quotidien de développeur, où mettre le curseur dans la connaissance de ses commandes?

Ici j’ai listé pour ma mémoire et pour votre information les choses communes qu’on peut faire avec git tag sans aller trop en profondeur.

#add a tag : lightweight(pointer to a commit) or annotated
#lightweight
git tag v1.4

#annotated
git tag -a v1.4 -m "my version 1.4"

#push tag information
#en effet un push classique ne pousse pas le tag vers le remote repository
git push origin v1.4

#list tag:
git tag

#search by pattern
git tag  -l "v1.8.5*"

Lightweight tag

C’est dans ce cas un simple label qui pointe vers un commit en particulier, donc ça rend plus lisible le commit.

Annotated tag

Ici le tag n’est pas seulement un pointeur avec un label lisible, mais il contient les informations sur le commit, et les informations sont tirées de l’index .git.

Effacer un tag localement et en remote

#effacer le tag v1.2
git tag -d v1.2
#effacer le tag distant
git push --delete origin v1.2

git push origin :refs/tags/v1.0  #utiliser pour faire le distingo entre une branche et un tag

Créer un tag sur un commit précédent (commit spécifique)

Il peut arriver que vous n’ayez pas taggé un commit lors d’une mise en production par exemple, dans ce cas vous pouvez tagger un commit plus ancien. Par défaut le tag se fait sur le HEAD qui est le plus récent.

Faites un git log -n ou un git log --pretty=oneline

#tagger sur un commit en particulier, tag annoté
git tag -a v1.2 9fceb02 -m "Message here"

Visualiser les tags dans github.com

Pour voir les tags, il suffit d’aller dans la page d’accueil de votre dépôt et de cliquer sur l’onglet « release ».

Tirer les tags depuis upstream

Si vous avez forké un projet, et que l’origin du projet (appelé upstream) a créé un tags, la synchronisation avec une branch ne fera pas apparaitre dans votre repository le tags.

Par contre en local vous pouvez tirer le tag:

git fetch --tags upstream
logo git

Commandes avancées en git ligne de commande

Je recommande d’utiliser Git en ligne de commande (sauf pour résoudre les conflits, dans ce cas les IDE sont d’une grande aide visuelle). Voici listées par thème des commandes que je considère essentielles, elle vous permettent de mieux voir le potentiel de Git, que même vous n’aurez pas soupçonné dans une logiciel graphique.

Git Commit

Connaître les fichiers modifié dans le dernier commit

git show --pretty="" --name-only sha
#le sha est le hash du commit, vous n'avez pas besoin d'avoir l'entièreté du hash, mais suffisamment pour discriminer le commit

Connaître les fichiers modifiés entre deux commits

git diff --name-only sha1 sha2
#sha1 et sha2 sont les hashs des commits 
#pour voir les différences entre les 10 et 5 derniers commits
git diff --name-only HEAD~10 HEAD~5
#il exsite beaucoup plus de variations mais l'essentiel est dans la première commande

Git branch

Montrer les branches existantes locale et en remote

$ git branch -a
#montrer seulement les branches en remote
$ git branch -r

Ajouter une description à une branche

$ git branch --edit-description
#pour voir la description
$ git config branch.mabranche.description
# en l'état si vous ne faites rien vous ne poussez pas ces descriptions, car elles sont écrites dans .git/config, si vous voulez les pousser, setter dans le config de cette manière :
$ git config --global branchdesc true
$ git merge --log <branch> #va mettre la description dans le message de merge
logo git

Les sous modules dans Git

UPDATE :

N’utilisez pas les sous module GIT, ils sont d’un usage délicat, googlez le sujet, vous verrez des blogs qui votent contre. Préférez cloner dans un sous répertoire et ignorer ce sous-répertoire.

 

Lorsque vous développez un module pour Prestashop ou Magento, les fichiers se logent dans un sous répertoire de la solution. Si en même temps vous devez versionner la solution globale, et le module, mais que vous voulez gérer deux dépôts Git différent, pour pouvoir par exemple distribuer le module indépendamment plus tard, la solution qui s’offre est la gestion des sous-modules de git.

 

Vous avez votre module dans une répertoire quelconque, et vous avez déjà versionné les scripts.

Vous allez dans un sous-répertoire de la solution globale, et vous clonez le dépôt du module :

$ git clone git@github.com:gituser/module.git

 

logo git

Git : Pull automatique du dernier push

Lorsque vous avez pratiqué suffisamment Git, à savoir pusher vos modifications et ensuite puller sur votre serveur de production, vous aurez un peu marre de ces manipulations répétitives que vous faites peut être une centaine de fois dans la journée.

La solution à votre problème si vous utilisez Github.com c’est d’utiliser les webhooks. Un prérequis à cette méthode est d’être en mode SSH pour pusher en ssh.

C’est quoi un webhook?

Un webhook est une page web (donc une url bien spécifique) qui sera appelée par Github. Elle sera appelée quand un événement se produit, en ce qui nous concerne c’est lorsqu’on push une branche vers Github, en ce qui  nous concerne c’est la branche master.

Comme cette page web est chargée, le script qu’il contient sera également exécuté, un peu comme les CRON job. Que doit contenir cette page? Je prends comme exemple un workflow où vous développez en php sous Windows, et que votre serveur de production est Linux. Ce que j’ai l’habitude de faire c’est quand j’ai mergé en local une branche feature avec ma branche master, je pousse la branche master vers Github. Ensuite je vais sur le serveur de production, je me connecte en tant que propriétaire du vhost en question (pas en root), et je fait un git pull pour avoir la dernière version du master.

Créer le webhook

C’est cette dernière étape qu’on va coder en php sur une page webhook que je vais appeler git.php, voici le code à l’intérieur:

<?php `git pull` ?>

Enregistrez votre fichier à la racine de votre serveur web de sorte qu’elle soit accessible de l’extérieur.

Les backticks (apostrophe inversés) servent à exécuter une commande shell dans un fichier php. Le fait d’appeler ce fichier php est équivalent à exécuter en mode console un git pull.

Configurer Github pour appeler cette page php

Allez sur votre répository sur Github.com, ensuite cliquez « Seeting », et puis sur la barre latérale « webhook ». L’exemple ci-dessous s’appuiera sur un événement de type push, c’est à dire que lorsque vous pusher vers votre repository, Github va envoyer une requête de type GET vers la page php que vous lui indiquez.

webhook avec Github

Bienb sûr vous pouvez faire plus de paramétrage, en cochant le dernier radio button, vous verrez tout un tas d’options, ce sont des choses plus sophistiquées que vous utiliserez sans doute avec un orchestrateur comme Jenkins.

logo git

Commentaire multiligne dans vos commits sous Windows

Pour aller au-delà d’une seule ligne de commentaire voici la syntaxe :

git commit -m « ligne 1″^

Plus?

Plus? « Ligne 2″^

Plus?

Plus ? « Ligne 3 »

Fin.

 

Syntaxe alternative :

git commit -m « blabla » -m « blabla »

La première ligne sera le titre et les suivante le corps de texte.

logo git

Git branch commandes utiles

Créer une branche dans Github

Vous utilisez sans doute Github seulement pour la gestion de version avec la branche master (celle qui va en production).

Github vous a changé la vie car il vou smémorise absolument toutes les version de votre code. Il vous permet de revenir à un état antérieur si vous avez fait une gaffe.

Branching

Le branching consiste à créer une variante du dépôt de référence (appelé Master), de travailler dessus sans le moindre risque de toucher au master puisque logiquement différent donc mutuellement exclusif). Quand vous aurez fini de travailler sur la branche, vous pourrez fusionner avec le dépôt de référence !

Bien sûr il risque d’avoir des conflits de fichier, dans ce cas le système Git vous demande de valider à la main.

Commander pour créer une branche à partir du dépôt de référence :

$git branch votre_branche
$git checkout votre_branche

ces commandes ci-dessus sont souvent résumées en une seule commande :

$ git checkout -b votre_branche

La commande checkout va pointer votre espace de travail vers la branche. Donc vous quittez la branche de référence (ou master).

où votre_branche est le nom de votre branche.

Quand vous  voulez commiter vos changement au code, vous faites vos commande habituelles:

$ git commit -m 'ajout fonction xyz'
$ git push origin votre_branche

Pour fusionner la branche votre_branche avec le master, revenez vers le master

$ git  checkout master
$ git merge votre_branche

et pour effacer votre_branche, faites la commande ci-dessous:

$ git branch -d votre_branche

Pour des explication plus en détail (en anglais) voir cette page.

Renommer une branch local

#allez à la branch que vous voulez renommer 
$ git checkout vieux_nom
$ git branch -m nouveau_nom

Renommer une branche distante

Si vous avez déjà poussé la branch dans le dépôt distant, il vous fautdra cette commande supplémentaire ensuite:

git push origin -u nouveau_nom
#simplement effacez l'ancienne branche
git push origin --delete vieux_nom
logo git

Git remote changer d’url pour votre repository

Dans l’article précédent je vous ai montré comment générer une clé SSH pour ne plus à avoir à taper de mot de passe.

Si vous avez commencé à utiliser Github en tapant votre identifiant et mot de passe, il y a de grandes chances que vous accédiez à votre repository via une url web de type https.

Accéder à votre repository en https ou en ssh

Sachez qu’il est possible d’accéder à votre repository depuis un autre chemin.

Supposons que votre repository soit actuellement sur:

https://github.com/votre_nom/repository.git

Pour vérifier à quelle url vous allez pusher faites la commande suivante :

git remote -v

En ayant activé vos clé SSH, vous avez sans doute eu un message du type « Github doesn’t offer shell access »

Si vous utilisez SSH il faut switcher sur une url du type:

git@github.com:votre_nom/repository.git

Sachez que cela n’est possible que si vous avez mis votre clé SSH sur le site de Github.com. Utilisez la commande suivante :

git remote set-url origin https://github.com/USERNAME/REPOSITORY2.git

refaites une commande

git remote -v

pour vérifier.

Pour revenir en mode https

git remote set-url origin git@github.com:USERNAME/REPOSITORY2.git

logo git

Installer Git sur votre machine Linux Debian

Si vous êts déjà en Root:

apt-get install git-core

Si vous n’êtes pas en Root :

sudo apt-get install git-core

ou

su root

puis

apt-get install git-core

Créer un repository  à partir d’un projet existant

Aller dans le répertoir racine du projet, et faire

$ git init

$ git add .

$ git commit

Quelques commandes Git

Générer un fichier pour ignorer les fichiers à versionner :

Qu’est-ce qu’on n’a pas envie de versionner? Ce sont les fichier de configuration, les fichiers des vendor tierces.

Il faut générer un fichier gitignore et mettre dedans les fichiers et répertoires.

$ touch .gitignore

il suffit de créer un fichier .gitignore et d’y mettre les fichiers à exclure. Pour exclure un répertoire mettez dans le fichier gitignore:

folder/**

pour exclure un fichier ajouter dans le fichier gitignore

nom_fichier

Si vous avez des fichiers committés que vous voulez exclure, il faut les enlever de la staginf area

$ git rm --cached nom_fichier

$ git rm -r --cached repertoire

Dans le cas ci-dessus on a retiré un répertoire entier avec récursion (dna sle cas où il y aurait des sous-répertoires.

Ajouter le nom du repository pour un push initial

git remote add origin youruser@yourserver.com:/path/to/my_project.git

logo git

Github pusher sans mot de passe

Lorsque que vous êtes sous windows et que vous travaillez avec Github, au début c’est génial car cela vous permet de faire un grand bon en avant, le versionning rien de mieux pour faire des amélioration de votre logiciel de façon incrémental sans avoir à gérer les différentes version en renommand les nom de fichier avec les dates.

Seulement au bout d’un moment vous devez taper sans cesse votre login et mot de passe à chaque fois que vous voulez pusher ou puller vos modification

Les clés SSH à la rescousse !

Il est possible de se passer de taper le login et mot de passe à chaque fois que vous devez pusher ou puller.

Il faut simplement utiliser les clé SSH publiques et privées.

Si vous êtes sous Windows, vous utilisez sans doute Git Bash pour commiter vos modifications, c’est dans ce même git bash que vous allez générer vos clé publique et privée.

Tapez la commande :

ssh-keygen -t rsa -C "your_email@example.com"

(Sous Linux idem)

Quand vous aurez le message : Enter passphrase (empty for no passphrase):

entrez un mot de passe (ne l’oubliez pas vous en aurez besoin).

Vos clés sont générées et sauvée dans le répertoire .ssh, sous Windows allez dans le répertoire utilisateur pour le trouver.

Informer Github de votre clé RSA

Maintenant il faut copier le contenu de votre clé publique dans Github.com

  1. Allez dans Github.com Settings
  2. Barre à gauche cliquez sur SSH Keys
  3. Donnez une titre et collez le texte de votre clé publique et cliquez sur Add KEy

Voilà c’est tout !

Dernière astuce pour les plus paresseux :

Maintenant quand vous allez commiter il ne vous sera plus demandé l’identifiant et le mot de passe mais par contre vous aurez à rentrer la passphrase. Pour ne pas à avoir à entrer cette passphrase à chaque fois que vous commitez, vous allez devoir utiliser le ssh agent pour stocker l’information.

eval `ssh-agent`

ssh-add

vous aurez à entre de nouveau le passphrase. Mais vous n’aurez à entrer qu’une fois seulement  la passphrase à chaque nouvelle session de git bash.

Pour aller encore plus loin :

Pour n’avoir plus à entrer de passphrase du tout il vous faudra écrire un script shell qui se lance automatiquement à chaque démarrage de git bash.

le -s va le mettre en tâche de fond.

Pourquoi cela ne marche toujours pas?

En fait il faut changer de représentation d’url, ce post vous en dit plus sur les url chez Github.

Autre méthode pour ne pas avoir à retaper le mot de passe à chaque fois

Voici la commande pour ne pas avoir à retaper le mot de passe :

git config --global credential.helper store

La prochaine fois que vous allez faire un git pull, vous allez entrer votre identifiant et mot de passe. Mais les fois suivantes, vous n’aurez plus besoin de le faire.

Astuce si vous voulez que cette mémorisation ne dure qu’un certain temps, le timout est en secondes.

git config credential.helper cache <timeout>
git versioning

Git publickey access denied

Lorsque vous avez ce message d’erreur alors que vous pensez n’avoir rien fait et que cela marchait très bien il y a peu de temps, cela veut tout simplement fdire que la clé public n’est pas atteignable, et donc l’accès au repository de Github vous est refusé.

Une des raisons qui m’est arrivé est que j’ai voulu changer le répertoire par défaut pour un site, car je voulais tomber sur le répertoire public_html après le login en ssh.

Avant quand je me loggais je tombait sur /home/monsite, mais je voulais tomber sur /home/monsite/public_html (je suis sous Debian)

J’avais créé ma clé ssh dans le répertoire /home/monsite/.ssh

Après avoir fait cette modification (modifier le fichier /etc/passwd), je ne pouvais plus faire un git pull, j’avais le message d’erreur « access denied ».

Récapitulons, git pense trouver ma clé ssh dans le répertoire /home/monsite/public_html/.ssh, mais en fait ce n’est pas à cet endroit qu’elle a été créée.

J’ai dû modifier le fichier /etc/passwd pour retrouver l’ancien paramétrage.

git versioning

Reconstruire un repertoire git quand il n’existe plus

Récemment j’ai changé de serveur un site entier, mais j’ai oublié de copier le répertoire .git !

Donc il m’était impossible de faire un pull pour avoir la dernière version sur mon serveur de production !

Pour ce faire il faut recréer un répertoire .git dans le serveur de production.

git init

git branch -d testbranch

git add .

git commit -m "import fichiers locaux"

Ensuite il faut configurer le repository distant

git remote add origin git@github.com:/compte/projet.git

#télécharger les fichiers distants

git fetch --all

revenir à la branche master

git checkout remotes/origin/master
git checkout -b master

Effacez la branche test

git branch -d testbranche

Dans mon cas j’avais un répertoire nouveau que j’ai accidentellement ajouté, il m’a fallut revenir à un commit précédent du repository distant, effacer la branche master, et créer de nouveau la branche master à partir du commit précédent.

Retour en haut