Git¶
Qu’est-ce que Git ?¶
Git un outil pour gerer du code. Ce dernier « dissecte » les changements sur un fichier plat, en fait une copie, et propose de ne mettre à jour qu’une partie précise du code. De même, il permet de différencier ses versions. Bref, nécessaire à tous développeurs ou groupe de développeur.
Installation¶
Rien de très compliqué, ça reste là principalement pour une cohérence de structure avec les autres docs :
apt install git
Configuration¶
Sur tous les postes de développement, certains paramètres sont à configurer sur GIT. Pour ma part, je désire avoir un nom de branche par défaut, ma signature GPG automatiquement et mettre en cache mon login/mdp pendant au moins 15 minutes lors d’un push.
Paramétrage de base¶
git config --global init.defaultBranch master
git config --global core.editor "vim"
git config --global user.name "Lucas FILIPPI"
git config --global user.email "Lucas.FILIPPI@luclis.fr"
Clé GPG¶
Afin de prouver que les commits viennent bien de vous, il est une bonne pratique de les signer. Pour cela, git propose de se servir de GPG.
cat > ./gen_key <<EOF
%ask-passphrase
#Key-Type: RSA
Key-Type: EdDSA
Key-Curve: Ed25519
Key-Length: 4096
Key-Usage: cert
#Subkey-Type: RSA
Subkey-Type: EdDSA
Subkey-Curve: Ed25519
Subkey-Length: 4096
Subkey-Usage: sign
Name-Real: Lucas FILIPPI
Name-Comment: Lucas FILIPPI@OP3.2
Name-Email: Lucas.FILIPPI@luclis.fr
Expire-Date: 10y
EOF
gpg --batch --generate-key ./gen_key
rm ./gen_key
git config --global commit.gpgsign true
git config --global user.signingkey $(gpg --list-keys --with-colons --with-fingerprint | awk -F: '/:::::s:::::/ {print $5 }')
Il ne reste plus qu’à entrer votre clé publique côté serveur. Pour la récupérer, il suffit de lancer cette commande :
gpg --armor --export $(gpg --list-keys --with-colons --with-fingerprint | awk -F: '/:::::s:::::/ {print $5 }')
Vérifier sa clé GPG¶
Certains utilistaires proposent de vérifier sa clé GPG. Cela permet d’ajouter une sécurité supplémentaire.
Sur Gitea, il faudra penser à utiliser la seconde clée pour signer le message, je ne sais pas pourquoi mais gitea récupère l’ensemble de la chaîne.
echo "TOKENTOKENTOKENTOKEN" | gpg -a --default-key $(gpg --list-keys --with-colons --with-fingerprint | awk -F: '/:::::s:::::/ {print $5 }') --detach-sig
Cache de connexion¶
Afin de ne pas avoir à rentrer son code à chaque commit, on peut mettre ce dernier en cache pendant une courte durée. Je l’ai réglé à 5 minutes. C’est la valeur par défaut, mais ça permet de garder l’option.
git config --global credential.helper 'cache --timeout=300'
Automatiser des commits sur une branch de developpement¶
Mon objectif ici est de gérer un mini-historique de mes fichiers. Pour cela, je travaille régulièrement sur une branche « WIP ». Je souhaite généraliser à chaque repos git que j’ai cette branche. Une fois ces branches généralisées, je veux que mon PC commit de façon automatique (et non signée, on s’en fout pour l’instant), chaque fichier de façon individuel, puis fasse un push. Le commit auto doit se faire toutes les heures, le push sur WIP toutes les 4h. Après, je ferais du rebase pour fusionner mes commits (peut-être automatiquement ?).
Sécurisation¶
Utilisation¶
Création d’un template git¶
Il est d’usage d’avoir un premier template avant de commencer à faire d’autre dépot. Ce dernier permet d’assurer d’avoir toujours les fichiers de bases sur tous les autres dépots qui vont suivre. Il peut être modulé en fonction du langage sur lequel on écrit. Pour ma part, j’utilise un template générique pour tout mes dépots. Il peut avoir plus de donnée que nécessaire, mais ce n’est pas (encore) grave. N.B Je ne sais pas comment retrouver la licence CC-BY-NC-SA. Il doit bien y avoir un moyen de la télécharger, mais je ne sais pas où.
mkdir ./Template
git init
#Téléchargement de la licence CC.
cat > ./README.md <<EOF
# Template Repository
This is a repository template for my next repos. Except when mentionned, all my work is under [license CC BY NC SA](https://creativecommons.org/licenses/by-nc-sa/4.0/) which mean that you can use and share what you see here as soon as you make a link to my ressources or my pseudo (*luclis*) and you do not sell my work. It seems acceptable to share it on a site which is self-managed thanks to advertising, the limit remains not to get rich on my work.
EOF
mkdir -p ./github/issue_template/
cat > ./github/issue_template/script.md <<EOF
---
name: "Bug script"
about: "Permet de remonter un bug sur un script"
title: "[SCRIPT] "
labels:
- bug
---
#BUG ISSUE
**Script** : *Mettre le nom du script impacté. Penser également à le changer dans le tag du titre.*
**Constat** : *Quel est le problème rencontré*
**Risque/Problème** : *Pour quel raison ce problème est-il bloquant ?*
**Solution** : *Quel solution théorique permettrait de résoudre le problème ?*
**Suggestion** : *Si vous avez une solution, on vous écoute ici !*
**Complément** : *Toutes informations supplémentaires pour mieux comprendre le problème*
EOF
git add .
git commit -m "Initial commit"
git remote add origin https://git.luclis.fr/Lucas.FILIPPI/Template
git push -o repo.private=false -o repo.template=true -u origin master
Vous voilà avec un dépot sur votre git public et marqué comme un template.
Supprimer un commit git¶
Je compte pas le nombre de fois où j’ai commit un truc, puis vu que j’étais pas sur la bonne branche. En attendant d’activer la protection des branches et de m’empecher de commit sur Master, j’ai cherché comment annuler les derniers commits. L’objectif final est de garder une branche WIP que je peux rebase comme je le désire et foutre le brin dedans et une branche master qui soit toujours propre.
Le plus simple, quand tu viens tout juste de t’en rendre compte, c’est de faire un reset soft : git reset --soft HEAD~1 (ici 1 comit en arrière).
Sinon, tu peux aussi rebase un peu en avant : git rebase HEAD~4 (ici jusqu’à 4 commit en arrière) et supprimer les commits non désirés.
Git Hooks¶
Il y a plusieurs style de hooks. Leurs noms sont assez logiques dont je ne repars pas dessus. Le principe est assez simple, il s’agit d’un script de son choix qui est lancé quand on arrive dans le cas précisé. Pour info, il en existe 27 types :
applypatch-msgpre-applypatchpost-applypatchpre-commitpre-merge-commitprepare-commit-msgcommit-msgpost-commitpre-rebasepost-checkoutpost-mergepre-pushpre-receiveupdateproc-receivepost-updatereference-transactionpush-to-checkoutpre-auto-gcpost-rewritesendemail-validatefsmonitor-watchmanp4-changelistp4-prepare-changelistp4-post-changelistp4-pre-submitpost-index-change
Pre-commit hook - Restreindre les commits dans le temps¶
Mon objectif ici est de travailler avec des branches temporaires. Je veux me servir de ça dans le cas de mes write-up Hacking. L’objectif est de me permettre d’avoir des branches notretired pas trop loin de ma master, afin que quand je les merge, je puisse faire du ff ou ne pas trop pourrir mon arbre de commit.
Note : Il n’est pas possible de faire plusieurs fichiers pre-commit. Mais peut-être que l’on peut faire un « include-like » style bash ./branch-date-check ? Comment on gère les code retour ?
lucas@OP3:~/Github/test$ cat ./.git/hooks/pre-commit
#!/bin/bash
## Branch-date-check
# Récupère le nom de la branche actuelle
branche_actuelle=$(git rev-parse --abbrev-ref HEAD)
date_actuelle=`date +'%m'`
mois_branche=`echo $branche_actuelle | cut -d "-" -f 2`
annee=("1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12")
# Vérifie si la branche actuelle est dans la liste des branches non autorisées
for mois in "${annee[@]}"
do
if [[ "$mois_branche" == "$mois" ]]; then
if [[ "$date_actuelle" > "$mois" ]]; then
echo "Refus : Les commits ne sont pas autorisés après la date limite sur cette branche."
exit 1
fi
fi
done
# Autoriser le commit pour les autres branches
exit 0
On remerciera chatGPT pour le script, j’ai du le retravailler, mais il est efficate. Petit test après, on voit que ça fonctionne bien.
lucas@OP3:~/Github/test$ git switch notretired-12
lucas@OP3:~/Github/test$ echo '333' > file4
lucas@OP3:~/Github/test$ git add file4
lucas@OP3:~/Github/test$ git commit -m "Test 4 - devrait planter"
Refus : Les commits ne sont pas autorisés après la date limite sur cette branche.
lucas@OP3:~/Github/test$ rm file4
lucas@OP3:~/Github/test$ git switch notretired-12
Basculement sur la branche 'notretired-12'
lucas@OP3:~/Github/test$ echo '333' > file4
lucas@OP3:~/Github/test$ git add file4
lucas@OP3:~/Github/test$ git commit -m "Test 4 - devrait marchr"
[notretired-12 98be65b] Test 4 - devrait marchr
1 file changed, 1 insertion(+)
create mode 100644 file4
Pre-commit hook - Forcer la signature sur différentes branches¶
Le contexte ici est simple, je veux que chacun de mes commits soient signés.
# Vérifie si le commit est signé sur toute les branches sauf WIP
branche_actuelle=$(git rev-parse --abbrev-ref HEAD)
if ! [[ $branche_actuelle == 'WIP' ]] ; then
if ! git log --pretty=%G? -n 1 | grep -q "^G$"; then
echo "Le commit n'est pas signé. Veuillez signer votre commit avant de le valider."
exit 1
fi
fi
Post-commit hook - Générer un pdf automatiquement¶
Ici, je veux automatiser la création d’un pdf dès que je commit un document md. Pour cela, je vais utiliser le hook post-commit.
sudo apt install pandoc texlive-latex-extra texlive-xetex texlive-latex-recommended
Modification du gitignore¶
Comme les fichiers pdf générés sont des copies des fichiers markdown, je n’ai pas d’intérêt à les push sur le git ni à les commit. Je vais donc dire à git de ne pas les prendre en compte. Je précise que cette commande doit être lancée depuis un repo git. C’est plus pratique pour dire à git d’ignorer certain type de fichier sur un repo … Logique ?
cat <<EOF >> $(git rev-parse --show-toplevel)/.gitignore
# Ignore PDF output
*.pdf
EOF