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.

This is clear, but if we do that and run crowdin download in the main branch right after, we get translations from feature/X branch. If these strings were translated in feature/X branch in crowdin and not in main branch in crowdin, how does crowdin connect it and downloads correct translations?
e.g.

  • (git) feature/X – change source string from "key": "initial value" to "key": "new value"
  • run crowdin upload sources --branch feature/X
  • (crowdin) feature/X – add translations for language FR for “new value”
  • (git) merge feature/X into main
  • run crowdin upload sources (now we update source string in main crowdin branch based on our main git branch value that we got from feature/X git branch)
  • run crowdin download

this gives us new correct translations for FR language with translated “new value”

this behavior is expected, but we don’t understand what leads to it, cause we didn’t translate the new value of the source string to FR language in main crowdin branch. How crowdin knows that it should take FR translation for "key": "new value" from feature/X crowdin branch when we run crowdin download after updating only sources in the main branch?

Hello @teki.mayflower :slight_smile:

Duplicates or TM pre translation may result in this.

we don’t understand what leads to it, cause we didn’t translate the new value of the source string to FR language in main crowdin branch.

If the key is translated even once (translations for language FR for “new value”), following duplicates/tm logic, this translation will be applied to any similar key within the project.

Alternatively, you might have uploaded both translation and source, in case you merged branches in Github. The connector support translation upload as well.