Les fichiers de langue sont du code. Ils sont versionnés, ils sont déployés, et l’application se comporte mal sans eux. Les garder dans Git est le bon choix par défaut — la question est comment, car l’approche naïve produit des conflits de merge et, pire, des traductions supprimées silencieusement.
Le mode d’échec
Deux développeurs, deux feature branches, chacun ajoutant des chaînes.
Le développeur A pousse les fichiers de langue mis à jour vers la plateforme de traduction. Le développeur B pousse les siens. Comme la plateforme traite un fichier source envoyé comme l’état complet actuel, le push de B supprime les chaînes de A — et avec elles tout le travail de traduction déjà effectué sur celles-ci.
Pendant ce temps, dans le dépôt, les deux branches ont régénéré en.yml avec des ajouts différents, si bien que le merge génère des conflits sur un fichier que personne ne veut résoudre à la main.
Les deux moitiés ont la même cause profonde : les fichiers de langue sont des artefacts complets, et plus d’un endroit fait autorité.
La solution : une seule branche possède les fichiers de langue
Désignez une seule branche comme source de vérité pour le push vers la plateforme de traduction. Tout le reste en découle.
Option 1 — push depuis main. Les feature branches sont mergées dans main au fur et à mesure qu’elles sont prêtes ; la CI pousse les fichiers source depuis main uniquement. Les nouvelles chaînes deviennent traduisibles dès qu’elles arrivent. Vous les livrez non traduites et elles se complètent lors d’un déploiement ultérieur.
Idéal pour les applications web qui déploient fréquemment. Nécessite un fallback sensé pour qu’une chaîne non traduite s’affiche dans la langue source plutôt que sous forme de clé.
Option 2 — une branche d’intégration dédiée. Mergez les fonctionnalités terminées dans une branche i18n à intervalles réguliers — disons chaque vendredi. Poussez depuis cette branche, laissez les traducteurs travailler, récupérez les résultats en pull et publiez. Rien n’est livré non traduit.
Idéal quand du contenu non traduit est inacceptable : produits réglementés, lancements marketing critiques, releases mobiles conditionnées par la revue du store.
Dans les deux cas, la règle est la même, et il vaut mieux l’imposer dans la CI que la documenter dans un wiki : seule la branche désignée pousse.
# Seule main pousse les chaînes source
- name: Push source strings
if: github.ref == 'refs/heads/main'
run: wti push
Quels fichiers committer
Committez les fichiers de langue source et cible. Ce sont des entrées du build.
Ne committez pas les artefacts générés — les fichiers .mo compilés à partir de sources .po, ou tout ce que produit votre build. Ils entrent constamment en conflit et ne portent aucune information que la source ne porte déjà.
Ajoutez une entrée .gitattributes pour que Git traite les fichiers de langue correctement dans les diffs :
*.yml diff=yaml
*.po diff=po
*.strings text
Et tenez les fichiers de langue à l’écart de tout formateur automatique qui réordonne les clés. Un formateur qui alphabétise un fichier YAML produira un diff touchant chaque ligne à chaque fois que le fichier est régénéré dans un ordre différent, ce qui rend chaque pull request de traduction impossible à relire.
Synchroniser dans les deux sens
Ce qui fait fonctionner tout cela, c’est qu’aucun humain n’est dans la boucle pour le cas courant. Une étape de synchronisation manuelle finit par être sautée, et les deux côtés dérivent silencieusement jusqu’à ce que quelqu’un remarque qu’une langue accuse des mois de retard.
Un dispositif qui fonctionne avec le CLI de WebTranslateIt :
wti push # envoie les fichiers source mis à jour
wti pull # récupère les traductions
wti status # complétude par langue
wti diff # ce qui changerait, sans rien changer
Au merge vers la branche désignée : wti push, fichiers source uniquement.
Chaque nuit, ou avant une release : wti pull, puis ouvrez une pull request si quelque chose a changé.
Sur chaque pull request : wti diff, remonté comme un check.
Ce dernier point est le plus utile et le moins connu. wti diff montre quelles chaînes un merge ajouterait ou supprimerait du projet de traduction sans rien changer. Cela transforme « ce refactoring supprime silencieusement 40 segments traduits » en une ligne visible dans la code review, exactement l’endroit où vous voulez le découvrir.
Il existe aussi une GitHub Action si vous préférez ne pas gérer le CLI dans vos fichiers de workflow.
Les traductions arrivent sous forme de pull request
Récupérez automatiquement ; faites atterrir le résultat sous forme de PR plutôt que d’un commit direct sur main.
Personne n’a besoin de lire les traductions — vous ne pourriez de toute façon pas relire la plupart d’entre elles. La raison d’être de la PR, c’est la forme du diff :
- Une suppression massive et inattendue signifie qu’un problème est survenu en amont : un fichier source poussé depuis la mauvaise branche, ou un mauvais import.
- Des changements sur une langue sur laquelle personne ne travaille méritent une question.
- Des changements structurels — indentation, ordre des clés, encodage — signifient qu’un outil a changé de comportement.
Automatisez la création, gardez le coup d’œil humain. Cela coûte quelques secondes et rattrape les échecs qui sont sinon invisibles jusqu’à la production.
Exécutez la validation sur cette même PR : intégrité des placeholders, complétude des pluriels, limites de caractères. Une traduction qui casse le build doit faire échouer le check, pas le déploiement.
Relire les changements sur les chaînes source
L’autre sens mérite lui aussi une relecture, et il n’en reçoit généralement aucune.
Changer une chaîne source n’est pas une action gratuite. Cela invalide la traduction existante dans chaque langue, et le coût croît avec votre nombre de langues. Une amélioration d’un seul mot sur le libellé d’un bouton coûte un aller-retour dans douze langues.
Ce qui mérite d’être signalé en review :
- Changements de formulation sur des chaînes existantes. L’amélioration justifie-t-elle une retraduction ? Parfois, clairement oui. Parfois, c’est une préférence qui coûte une semaine.
- Renommages de clés. Renommer une clé se lit généralement comme « supprimer cette chaîne, en ajouter une autre sans rapport », ce qui jette l’historique de traduction. La plupart des plateformes ne font pas la différence.
- Nouvelles chaînes sans contexte. Un commentaire de développeur fait partie de l’écriture de la chaîne, et son absence se relit comme l’absence d’un test.
Un check CI léger qui commente une PR touchant aux fichiers de langue — ceci change 6 chaînes source, affectant 12 langues — rend le coût visible au moment où la décision est prise.
Monorepos et projets multiples
Un monorepo contenant une application web, une application mobile et un site marketing pose une question : un seul projet de traduction, ou plusieurs ?
Plusieurs projets, une mémoire et une base terminologique partagées est généralement le bon choix. Chaque application a ses propres formats de fichiers, sa propre cadence de release et souvent ses propres traducteurs, si bien qu’un projet unique mélangeant strings.xml, Localizable.strings et en.yml produit une liste de segments que personne ne peut naviguer. Les séparer permet à chacun de rester cohérent.
Ce que vous ne voulez pas séparer, c’est la mémoire de traduction et la base terminologique. Les mêmes phrases apparaissent sur les trois surfaces, et tout l’intérêt est de les traduire une seule fois. Faites pointer les ressources de traduction de chaque projet vers une source partagée.
Dans la CI, cadrez la synchronisation par projet plutôt que de lancer une seule commande à la racine du dépôt :
(cd apps/web && wti push)
(cd apps/mobile && wti push)
Chaque répertoire porte sa propre configuration .wti, si bien que les identifiants et l’id de projet voyagent avec le code auquel ils appartiennent.
Une configuration de référence
En résumé :
mainpossède les fichiers de langue. Imposé dans la CI.- Au merge vers
main:wti push, source uniquement. - Sur chaque PR :
wti diffen tant que check, plus un commentaire quand les chaînes source changent. - Chaque nuit :
wti pull, ouvrez une PR si quelque chose a changé. - Sur cette PR : exécutez la validation, et faites regarder la forme du diff par un humain.
- Ne modifiez jamais les fichiers de langue cible à la main. Ils sont générés ; les modifications manuelles sont écrasées, et la personne qui les a faites apprend à ne plus faire confiance au pipeline.
Cette dernière règle est celle qu’on enfreint sous la pression des délais, et c’est celle qui détruit silencieusement la confiance dans tout le dispositif. Si une traduction est fausse, corrigez-la dans la plateforme afin que la correction survive au prochain pull.
Frequently asked questions
- Faut-il committer les fichiers de traduction dans Git ?
- Oui. Ils font partie du build, et l’application ne peut pas fonctionner correctement sans eux. Les garder dans le dépôt signifie que les traductions sont versionnées, relisibles et déployables via le même pipeline que le code.
- Comment éviter les conflits de merge dans les fichiers de langue ?
- Poussez les fichiers de langue depuis une seule branche, et laissez les traductions revenir sous forme de commits propres plutôt que d’être modifiées à la main. La plupart des conflits viennent de deux branches qui régénèrent indépendamment le même fichier, ce qu’une seule branche source désignée élimine.
- Faut-il récupérer les traductions automatiquement, ou les faire relire ?
- Récupérez-les automatiquement, mais faites atterrir le résultat sous forme de pull request plutôt qu’en commit direct. Personne n’a besoin de lire les traductions, mais quelqu’un doit voir le diff — une suppression massive et inattendue est le signal que quelque chose s’est mal passé en amont.
- Peut-on utiliser des branches Git pour la traduction ?
- Généralement pas. La plupart des plateformes de traduction modélisent un projet comme un état courant unique plutôt que comme un arbre de branches, si bien que pousser depuis deux branches les fait entrer en conflit. Le schéma qui fonctionne est une seule branche d’intégration désignée qui possède les fichiers de langue.
Keep reading
-
La localisation continue expliquée
Comment mener la traduction comme un processus continu en parallèle du développement, que faire des branches de fonctionnalités, et quand la localisation agile convient mieux.
-
QA de localisation : les validations qui détectent les chaînes cassées
Les vérifications mécaniques qui détectent les traductions cassées avant la release — placeholders, pluriels, HTML, limites de caractères — et pourquoi la relecture seule ne les trouve jamais.
-
Qu’est-ce qu’un système de gestion de traduction ?
Ce qu’un TMS fait concrètement, les problèmes qu’il résout et qu’un tableur ne résout pas, et comment savoir si votre équipe a dépassé le stade de l’échange de fichiers par e-mail.
-
CLI wti : synchroniser les fichiers de langue depuis le terminal (documentation)
Pousser les fichiers source et récupérer les traductions depuis le terminal ou depuis la CI.
Translate your app without the spreadsheet round-trip
WebTranslateIt reads the file formats and placeholder syntax described on this page, validates them as translators work, and syncs the results straight back into your repository.