datacraftGitversioningcollaborationbonnes pratiquesdata analyst

Git pour data analyst : les 8 situations qui font vraiment mal (et comment en sortir)

GP
Gaël Penessot

Le problème avec Git chez les data analysts n'est pas la commande commit. C'est ce qui arrive après : un notebook en conflit et illisible, un push rejeté avec un message hostile, un fichier de données de 300 Mo devenu impossible à retirer de l'historique.

Voici les 8 situations qui bloquent réellement, avec la sortie de secours pour chacune.

Situation 1 : le push est refusé

! [rejected] main -> main (fetch first)
error: failed to push some refs

Traduction : quelqu'un a poussé avant vous. Votre historique local et le distant ont divergé.

git pull --rebase
# resoudre les eventuels conflits, puis
git push

--rebase rejoue vos commits au-dessus de ceux des autres, au lieu de créer un commit de merge parasite. Sur un dépôt à plusieurs analystes, ça garde un historique linéaire et lisible.

Le réflexe à installer : git pull --rebase avant de commencer à travailler, pas seulement quand le push échoue.

Situation 2 : un merge conflict dans un notebook

Le pire cas, parce que le .ipynb est un JSON qui contient les sorties, les numéros d'exécution et les métadonnées. Deux personnes qui exécutent le même notebook produisent un conflit même sans changer une ligne de code.

La solution durable : ne jamais versionner les sorties.

uv add --dev nbstripout
uv run nbstripout --install

nbstripout s'installe comme filtre Git : il retire automatiquement les sorties et les compteurs d'exécution au moment du commit. Le fichier sur disque garde ses sorties, le fichier dans Git est propre. Les conflits chutent de 80 à 90 %.

Pour un conflit déjà en cours sur un notebook :

git checkout --ours notebooks/analyse.ipynb    # garder ma version
git checkout --theirs notebooks/analyse.ipynb  # garder la sienne
git add notebooks/analyse.ipynb

Résoudre un JSON de notebook à la main est presque toujours une perte de temps : choisissez une version, réappliquez la modif manquante dans Jupyter.

Situation 3 : j'ai committé un fichier de données de 300 Mo

Le git rm ne suffit pas. Le blob reste dans l'historique, et le dépôt reste lourd pour tout le monde, à chaque clone.

Si le commit n'est pas encore poussé :

git reset --soft HEAD~1        # annule le commit, garde les fichiers
git restore --staged data/gros_fichier.csv

S'il est déjà poussé, l'historique doit être réécrit avec git filter-repo, ce qui impose une coordination avec toute l'équipe (chacun doit recloner). C'est une opération à ne pas improviser.

La prévention coûte une ligne :

data/raw/*
data/processed/*
*.csv
*.parquet
!data/**/.gitkeep

Le .gitignore complet pour un projet data est détaillé dans structurer un projet Python data.

Situation 4 : j'ai committé un mot de passe

Cas particulier de la situation 3, avec une différence majeure : retirer le fichier ne règle rien. Dès qu'un secret est parti sur un dépôt distant, il est compromis.

L'ordre correct des opérations :

  1. Révoquer la clé ou changer le mot de passe. Immédiatement.
  2. Générer un nouveau secret.
  3. Le sortir du code, dans une variable d'environnement.
  4. Nettoyer l'historique si le dépôt est privé et l'équipe petite.

Inverser 1 et 4 est l'erreur classique : pendant que vous nettoyez l'historique, la clé est toujours valide.

Situation 5 : je veux annuler mon dernier commit

Trois cas, trois commandes différentes. La confusion entre les trois est la première cause de travail perdu.

Besoin Commande Effet sur vos fichiers
Annuler le commit, garder les modifs git reset --soft HEAD~1 Intactes, prêtes à recommitter
Annuler le commit et le staging git reset HEAD~1 Intactes, non stagées
Tout jeter git reset --hard HEAD~1 Détruites définitivement
Annuler un commit déjà poussé git revert <sha> Nouveau commit inverse, historique préservé

--hard est la seule commande Git qui détruit du travail sans filet. Sur une branche partagée, utilisez toujours git revert : il ne réécrit pas l'historique des autres.

Situation 6 : je dois changer de sujet, mais mon travail n'est pas fini

git stash push -m "analyse cohortes en cours"
git switch main
git pull --rebase
# ... urgence traitee ...
git switch ma-branche
git stash pop

git stash list montre la pile. Nommer les stash (-m) évite de retrouver trois stash@{0} anonymes une semaine plus tard.

Situation 7 : j'ai perdu un commit

Il n'est presque jamais perdu. Git conserve un journal de toutes les positions de HEAD pendant 90 jours.

git reflog
# 3f2a1b0 HEAD@{2}: commit: calcul des cohortes
git checkout 3f2a1b0
git switch -c recuperation

git reflog est la commande qui sauve, y compris après un reset --hard malencontreux. Elle mérite d'être connue avant d'en avoir besoin.

Situation 8 : mon collègue et moi modifions le même script

Le conflit sur un .py est normal et se résout à la main. Git marque la zone :

<<<<<<< HEAD
df = df[df["quantite"] > 0]
=======
df = df[df["quantite"] >= 1]
>>>>>>> feature/nettoyage

Vous gardez ce qui est correct, vous supprimez les trois marqueurs, git add, git rebase --continue. Rien de magique.

Ce qui réduit la fréquence de ces conflits, c'est le découpage en modules : deux personnes qui travaillent sur extract.py et transform.py ne se marchent pas dessus. Un fichier unique de 900 lignes garantit le conflit à chaque itération.

Le workflow minimal pour une équipe data

Pas de GitFlow, pas de release branches. Trois règles suffisent :

  1. main est toujours exécutable. Rien n'y arrive directement.
  2. Une branche par sujet, nommée type/sujet : feat/cohortes, fix/jointure-doublons.
  3. Une pull request, même sans relecteur. Elle sert de trace, et elle déclenche la CI qui lance les tests.

Le troisième point est celui qu'on saute quand on est seul, et c'est une erreur : la PR est ce qui branche vos tests pytest sur chaque modification.

Des commits qu'on peut relire six mois plus tard

Le format Conventional Commits demande dix secondes et rend l'historique navigable :

feat(cohortes): ajoute le calcul de retention a 90 jours
fix(jointure): corrige la duplication sur le referentiel produits
chore(deps): passe pandas en 2.3

Le test du bon message de commit : est-ce qu'il explique pourquoi, pas ce que le diff montre déjà ? update script échoue au test. fix(jointure): corrige la duplication sur le referentiel produits le passe.

S'entraîner sans risquer son dépôt d'équipe

Lire des commandes Git ne suffit pas. Ce qui bloque en situation réelle, c'est la panique quand le message d'erreur arrive et que trois personnes attendent le livrable.

Le simulateur Git gratuit rejoue exactement ces scénarios d'équipe : push rejeté, conflit sur notebook, commit à récupérer, dans un environnement où casser quelque chose n'a aucune conséquence. C'est la façon la plus rapide de transformer ces 8 situations en réflexes.

Une fois Git acquis, la suite logique est le reste de la chaîne : structure de projet, tests, CI, revue de code. C'est le parcours de la formation DataCraft, pour passer au niveau ingénierie.

Questions fréquentes

Faut-il versionner les notebooks ? Oui, mais sans les sorties, avec nbstripout. Un notebook sans sorties se diffe et se merge presque comme un fichier Python.

Faut-il versionner les données ? Non, sauf jeux de référence très petits (moins de 1 Mo, stables). Pour le reste, versionnez le code qui produit la donnée et le chemin vers la source.

GitHub, GitLab ou Bitbucket ? Sans importance pour un analyste : les commandes Git sont identiques. Seule l'interface de pull request change.

Faut-il apprendre rebase ou se contenter de merge ? git pull --rebase au quotidien suffit. Le rebase interactif pour réécrire l'historique est un outil de confort, pas une nécessité.

Livre Business Intelligence avec Python

Approfondir avec mon livre

"Business Intelligence avec Python" - Le guide complet pour maîtriser l'analyse de données

Voir sur Amazon →

Formation recommandée

DataCraft

Du notebook chaotique au repo production-ready : structure, tests, Git, CI. Le software engineering appliqué à la data, sur un fil rouge d'entreprise unique.

Voir la formation →

Ne manque rien de l'actualité data

Rejoins +1000 professionnels qui reçoivent chaque semaine mes analyses, conseils et découvertes data.

S'abonner gratuitement
Prochaine révision : Trimestre prochain