24

Today I tried to merge two git branches of a Qt project. Both branches had added some new strings and new translations for them. Now Qt's lupdate tool stores the line number of the source file where the translation is needed in the .ts files. As you can imagine the line numbers are not identical for two branches and when both translation files have been updated, this leads to hundreds of merge conflicts like this, for every single translation file:

<<<<<<< HEAD
 +        <location filename="../../src/network/mail/CSmtp.cpp" line="856"/>
=======
+         <location filename="../../src/network/mail/CSmtp.cpp" line="860"/>
>>>>>>> master

You might say just use one of the versions and run lupdate again, but that way you lose all new translations from one of the branches.

Other tools, like gettext, don't not have this problem, since they do not store line numbers.

What are some good approaches to avoid this problem in Qt?

SteakOverflow
  • 1,953
  • 13
  • 26

5 Answers5

12

From the lupdate man page:

-locations {absolute|relative|none}

Specify/override how source code references are saved in ts files. Default is absolute.

So use lupdate -locations none to eliminate all line numbers in the TS files. Use lupdate -locations relative to reduce the churn in line numbers: now, changes in line numbers will only affect the first string after each change, which might be an acceptable compromise if you use linguist with the source window open.

My preference is to commit to source-control just the version with -locations none. Any time I need the line numbers, I run lupdate locally to generate a temporary version with absolute locations. Make sure you don't commit the temporary!

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • Interesting to note that `lupdate` with _none_ will indeed delete the line numbers from existing TS files, but `lupdate` with line-numbers will not update the existing translations to add the context (I guess it would complete the new strings though). – ymoreau Jun 22 '17 at 08:55
4

One possible solution (mentioned in an answer to "Merge translation files (.ts) with existing .ts files") is to use lconvert. When this was introduced, in Qt 4.5:

The new lconvert filter tool facilitates conversion between file formats and can be used to perform other transformations on collections of translatable strings.

It involves a manual step (creating a second file with only the strings you want to merge), and then:

 lconvert -i primary.ts secondary.ts -o complete.ts

To complete the end result, the answer to "Translation file still working after modifying the source?" also mentions pylupdate4 your_project.pro as a way to update all the references to the lines in the ts file.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
4

You can drop the line numbers with lupdate too using -locations none. This will eliminate any conflicts with line numbers but you will lose the context of the strings in the sources. For .ui files there is also -no-ui-lines argument.

lupdate -locations none -no-ui-lines ...
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
svlasov
  • 9,923
  • 2
  • 38
  • 39
2
  1. Check-in an empty TS that is valid XML, e.g. ./i18n/myapp_de.ts

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE TS>
    <TS version="2.1">
    </TS>
    
  2. Run lupdate -verbose -no-obsolete ./src-folder/ -ts ./i18n/myapp_de.ts when sources changed.

  3. Don't ask why this nicely creates new translation entries and proper contexts without line numbers while it doesn't if TS file does not exist.

Simon Warta
  • 10,850
  • 5
  • 40
  • 78
0

If you merge using the ours or theirs strategy (see git merge doc at the MERGE STRATEGIES chapter), you will have all the translations from both branches:

git merge branch1 -X theirs
git merge branch2 -X theirs

Then run the lupdate command to fix the rong number lines.

Frodon
  • 3,684
  • 1
  • 16
  • 33