*

Git: hook commit-msg pour adopter les conventional commits


22/09/2020 git commit conventional commit

Les “conventional commits” apportent une formalisation des messages de commit git. Ils sont de la forme :

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Pour reprendre quelques exemples :

# Commit message with no body
feat: allow provided config object to extend other configs

# Commit message with scope
feat(lang): add polish language

# Commit message with ! to draw attention to breaking change
refactor!: drop support for Node 6

# Commit message with both ! and BREAKING CHANGE footer
refactor!: drop support for Node 6

BREAKING CHANGE: refactor to use JavaScript features not available in Node 6.

En forçant ce formalisme, le développeur est un peu moins tenté d’avoir un historique de commit du style :

fix  button
typo
add some tests
add some tests
...

Au lieu de faire un commit à chaque sauvegarde du fichier ou presque, il va commencer à “raconter une histoire” :

fix: button on home page does not work on IE6
docs: typo in the README file
feat: add some tests for module XXX

Cela a le mérite aussi de générer un changelog plus agréable à lire. Si en plus, on rajoute par ex un identifiant de ticket, on peut alors facilement retracer l’historique d’un changement et sa raison d’être :

fix(123): button on home page does not work on IE6
docs(211): typo in the README file
feat(175): add some tests for module XXX

Un peu à la manière de “Properly managing your .gitignore file”, on peut vouloir que le hook git s’applique à tous nos dépôts présents et à venir et ne pas avoir à contribuer le hook à chaque dépôt git.

# Create ~/.git-templates/hooks
mkdir -p ~/.git-templates/hooks
# Create commit-msg file and make it executable
touch ~/.git-templates/hooks/commit-msg
chmod +x ~/.git-templates/hooks/commit-msg

Ajoutons ensuite notre hooks dans ~/.git-templates/hooks/commit-msg :

#!/usr/bin/env python3
# Original source: https://github.com/prahladyeri/enforce-git-message/
# Extended with BREAKING CHANGE, exclamation mark support (!) and space before " : " for French people

import re, sys, os

examples = """+ 61c8ca9 fix: navbar not responsive on mobile
+ 479c48b test: prepared test cases for user authentication
+ a992020 chore: moved to semantic versioning
+ b818120 fix: button click even handler firing twice
+ c6e9a97 fix: login page css
+ dfdc715 feat(auth): added social login using twitter
+ b235677 BREAKING CHANGE: remove support for XXX
+ a234556 revert!: back to version X.Y.Z for component ZZZ
+ b123456 feat : we support space before : for French people :-)
"""

def main():
    pattern = r'(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|BREAKING CHANGE)(\([\w\-\s]+\))?!?\s?:\s.*'
    filename = sys.argv[1]
    ss = open(filename, 'r').read()
    m = re.match(pattern, ss)
    if m == None:
        print("\nCOMMIT FAILED!")
        print("\nPlease enter commit message in the conventional format and try to commit again. Examples:")
        print("\n" + examples)
        sys.exit(1)

if __name__ == "__main__":
    main()

Il faut ensuite indiquer à git que vos templates sont dans ce dossier :

git config --global init.templatedir '~/.git-templates'

Pour les dépots git existants, il faut réinitialiser votre dépôt git :

cd /path/to/git/repo
git init
Dépôt Git existant réinitialisé dans /path/to/git/repo/.git/

Vous pouvez alors commencer à travailler dans votre repo et valider le bon fonctionnement du hook.

Syndication

Restez informé(s) de notre actualité en vous abonnant au flux du blog (Atom)

Nuage de tags

kubernetes docker timeseries influxdb warp10 traefik grafana ansible kafka postgres elasticsearch python sécurité aws terraform mysql redis ovh tick cassandra cloud docker-compose git helm telegraf chronograf hashicorp ptsm swarm timescaledb dashboard rancher résilience test flux gcp gitlab log machine-learning monitoring podman prometheus spark vector architecture arm confluent devops gitlab-ci iac java kapacitor ksql microservice raspberrypi s3 serverless sql timescale vscode angularjs api bilan cert-manager cncf comptabilité container cérénit dns gke graphql influxdata ingress javascript nomad opensource operator optimisation perspective pipeline scaleway service-mesh ssh stream vault warpscript windows cli consul containerd csp documentation elastic flows forecast geospatial hpkp influxace iot jenkins kafka-streams kibana kubedb lambda lean licence maesh maintenance mariadb microsoft mobile nginx npm orientdb performance postgresql redhat registry rest rethinkdb reverse-proxy rook sauvegarde agile apm arima automatisation azure bash big-data bigdatahebdo ceph certificat challenge ci/cd cluster continous-delivery continous-integration cookie data dataviz deployment diff facebook fluxlang framework gdpr golang grav hsts http/3 https hypriot hébergement ia influxdays istio jq json k3s lets-encrypt linux load-balancer longhorn meetup molecule mongodb nosql nvidia openebs openssh ovhcloud percona php pip quasardb reaper replication rootless rpi rsyslog runc scale secrets société solr sre systemd tempo timezone tls virtualenv vitess vue.js wagtail warpfleet warpstudio yarn accessibilité acme agpl akka alerte alibaba amazon-emr amqp anomalie anonymisation anthos apache-pulsar ara arrow artefact audit banque bastion beam beat bme680 bootstrap bounded-context branche brigade browser buildah buildkit cahier-des-charges calico cassandra-reaper cd cdc cdk centos centralisation-de-logs certificats cgroups chart checklist chrome ci cilium cloud-init cloud-native cloud-storage clusterip cnab cni co2 cockroachdb code codeurs-en-seine commit confluence conftest context continous-deployment conventional-commit coreos cors covid19 cqrs crash cri cron crontab csi csrf css curl d3.js daemonset data-engineer data-pipelining data.gouv.fr databricks datacenter datatask date date-scientist dbt ddd debezium debian delta deprek8 desktop devoxx dig discovery distributed-systems dive docker-app docker-hub docker-registry docker-swarm dockershim documentdb dog dokcer données-personnelles draft drop-in duration déploiement développement-du-site e-commerce ebs ec2 edge elassandra electron elk engineering entreprise ergonomie etcd euclidia event-sourcing faas faisabilité falco falcor feature-policy fec fedora feed filebeat firebase firefox fish flash flask fleet flink fluentd formation foundation frenchtech frontend fsync fullstack git-filter-repo github gitignore glacier glowroot go google google-cloud-next gpg gpu grid géospatial hacker hadoop haproxy harbor hdfs header holt-winters html html5 http hue iaac ibm immutable incident index indluxdata influxcloud infrastructure-as-code ingénierie inspec jquery jwt k3d k6 k8s k9s kaniko katz kotlin kubeadm kubecon kubectl label laravel leap-second lens letsencrypt libssh linky linter liste-de-diffusion lmap loadbalancer logstash logstatsh loi loki lstm mailing-list management maturité mesh mesos message metabase metallb micro-service minio mot-de-passe mqtt multi-cloud médecine métrique network newsletter nodeport notebook null object-storage observability observabilité opa opendata openhab openmetrics openshit openstack openweb opnsense over-engineering packaging pandas parquet partiql password persistent-volume-claim pico pipenv pod portainer portworx prediction prescience production promql prophet prévision psp ptyhon publicité pubsub pulsar push pyenv pérénnité qualité quay questdb queue quic ram rambleed raml react readme recaptcha recherche redistimeseries reindex reinvent reliability remote-execution repository responsive revocation revue-de-code rexec rgpd rhel rkt rolespec root rpo rto rust rwd safe-harbor sarima scalabilité scanner schema scp sdk search select serverless-architecture service service-account service-worker setuptools sftp sha1 sharding shell shipyard sidecar souveraineté-numérique spectre spinnaker spécifications sqlite sri ssh-agent ssl stabilité stash statistique storage sudo superset suse sympa sysdig syslog-ng sérénité template terracost terrascan test-unitaire tidb tiers time timer timestream training transformation travail trésorerie tsfr tsl ubuntu unikernel unit ux velero vendredi victoria-metrics vie-privée virtualbox virtualisation vm vnc volume voxxeddays vpc wasm web wireguard yaml yq yubikey