How does Crowdin choose which translations to use on upload sources?

Hi Crowdin team,

We’ve run into an ambiguous situation when working with branches and uploading source files. Below are two scenarios:


1. Problematic case

  1. In GitLab, create branch feature/X

  2. In source file (e.g. en.json ), update the text for key MY_KEY

  3. Run:

    crowdin upload sources branch --branch feature/X
    

    – this creates branch feature/X in Crowdin

  4. Manually modify en.json and translation files in our code

  5. Merge feature/X into main branch

  6. From project root, run:

    crowdin upload sources
    crowdin download
    
  7. Result: downloaded files contain empty strings for the updated key instead of translations


2. Normal case (everything works)

  1. In GitLab, create branch feature/Y

  2. In source file (e.g. en.json ), update the text for key MY_KEY

  3. Run:

    crowdin upload sources branch --branch feature/Y
    

    – this creates branch feature/Y in Crowdin

  4. In Crowdin’s UI, switch to branch feature/Y and add translations for the new text

  5. Locally run:

    crowdin download branch --branch feature/Y
    

    – you see the new translations

  6. Merge feature/Y into main

  7. Run:

    crowdin upload sources
    crowdin download
    

    – all translations are pulled in correctly


Our questions

  1. Master string when upload
    How does Crowdin determine which translations/strings is “MASTER” when running crowdin upload sources (without --branch)?
  2. Conflicting edits across branches
    If the same string is modified in two different branches, how does Crowdin decide which version is “current” and which translations to download?

We’d appreciate any guidance on how to keep our workflow consistent and avoid losing translations.

Thanks in advance, Alex

Hi @rabbdroid

Here are the direct answers:

  1. How does Crowdin determine the “MASTER” string when running crowdin upload sources (without --branch)?

The first string uploaded into the project is considered a master, regardless of whether it’s a development or master branch. If it is deleted, then 2nd uploaded will become the master and so on.

When you run crowdin upload sources without specifying a branch, Crowdin will upload source strings as it is written in your source path (CLI configuration) into root/master.

  1. If the same string is modified in two different branches, how does Crowdin decide which version is “current” and which translations to download?

Crowdin handles strings in different branches as separate entities tied to their respective branches. There isn’t an automatic “conflict resolution” that merges translations across branches into the main branch.

If a string is updated in feature/X and translated there, those translations belong to feature/X in Crowdin. When you merge feature/X into your local main and then crowdin upload sources to Crowdin’s main branch, the new source string appears in Crowdin’s main branch.

Working with duplicates in Crowdin can help here. Just enable duplicate management in your Crowdin project settings (look under “Import”).

Choosing “Show within a version branch (regular detection)” or “Hide (regular detection)” is key. Combined with a good Translation Memory (if needed), it is highly effective for your branching workflow, preventing those “empty string” issues.