25

Every time we make changes to the .strings files (for iOS localization) from different branches, we will have conflicts.

The reason seems to be that git consider the .strings as binary files instead of text files. Sometimes it is a little annoying because git won't help merging the changes automatically, again, because they are considered as in binary format.

Is there any git settings that will force it to consider a file as text file.

I notice that both SourceTree and GitLab won't be able to tell that it is text file. But XCode itself will be able to show us the diff. Not sure this is related or not.

enter image description here

Yuchen
  • 30,852
  • 26
  • 164
  • 234

9 Answers9

28

Create a .gitattributes file at the root of your repo with this contents:

*.strings diff

More information: https://git-scm.com/docs/gitattributes

Jonathan.Brink
  • 23,757
  • 20
  • 73
  • 115
  • 2
    @slawomir-jaranowski suggests `text` while you suggest `diff`; what is the difference? – Sukima Mar 24 '16 at 18:09
  • Using `diff` will cause files of that type to be diffed using your default difftool – Jonathan.Brink Mar 24 '16 at 18:19
  • 1
    In case you want to add this as a global setting for your user (instead of committing to the project), you can run `git config --global core.attributesfile ` where the path can be something like `~/.gitattributes` – Luiz Dias Jul 11 '22 at 17:20
22

None of the solutions worked for me, so I did some more research and at this link I found out this:

  • in your project main directory, create or edit a .gitattributes file adding this line:

    *.strings diff=localizablestrings
    
  • in the .gitconfig file in your home directory, add these lines:

    [diff "localizablestrings"]
    textconv = "iconv -f utf-16 -t utf-8"
    

This did the trick.

il3v
  • 472
  • 4
  • 15
  • I think this should be marked as the correct answer. Only solution that made git diff work and show the changes clearly as readable text. For me, at least. Note that .gitconfig is in your home directly, .gitattributes is something you add to your project directory. This excellent post says so, but easy to gloss over (well, I did the first time!) – Andy Weinstein Jul 10 '22 at 12:55
13

After trying Jonathan or Slawomir's solution, I am still not able to see the diff properly. They are still being considered as binary file.

I finally figure out that the our localizable.strings file are not in UTF-8 encoding but in UTF-16 encoding. After changing the encoding back to UTF-8, it works fine.

Is it okay to change the encoding? Yes, it is. It is actually recommended by Apple to use UTF-8.

Note: It is recommended that you save strings files using the UTF-8 encoding, which is the default encoding for standard strings files. Xcode automatically transcodes strings files from UTF-8 to UTF-16 when they’re copied into the product.

[reference]

How do you know what encoding that file is? See this for command line and this for Xcode:

file -I vol34.tex 

See comments below, you may have to change the encoding of the file manually:

iconv -f UTF-16 -t UTF8 file.strings
Community
  • 1
  • 1
Yuchen
  • 30,852
  • 26
  • 164
  • 234
  • 1
    I tried to do this with Xcode 9.2 and it didn't actually change the file encoding. It only changed what the `.xcproj` file thought the file encoding was. Fixed with `iconv -f UTF-16 -t UTF8 file.strings`. – Greg Apr 19 '18 at 17:23
  • 1
    @EdwardThomson lol. Thanks! But I guess I'll leave the accepted answer as it is for now. Jonathan's answer did help me at that time IIRC. If this answer ever gets more votes than that answer later, I'll change the green tick ;) – Yuchen Apr 19 '18 at 22:01
  • For me, converting to UTF-8 also did the trick. However, I am using `genstrings` which generates the file in UTF-16LE, so I need to convert it back to UTF-8 each time its run. Further, converting the file to UTF-8 using both `iconv` and Xcode didn't work for me, I ended up using VS Code. – Ric Santos Mar 13 '21 at 09:48
1

Please add in your project root directory file .gitattributes with content:

*.strings  text

Now git will recognize your files .strings as text files.

Slawomir Jaranowski
  • 7,381
  • 3
  • 25
  • 33
  • 2
    @jonathan-brink suggests `diff` while you suggest `text`; what is the difference? – Sukima Mar 24 '16 at 18:09
  • From manual: Setting the text attribute on a path enables end-of-line normalization and marks the path as a text file. End-of-line conversion takes place without guessing the content type. – Slawomir Jaranowski Mar 24 '16 at 18:13
  • 1
    And: A path to which the diff attribute is set is treated as text, even when they contain byte values that normally never appear in text files, such as NUL. – Slawomir Jaranowski Mar 24 '16 at 18:13
1

Here is my variant of the script I used on my mac. I need to convert all .strings files to utf-8 encoding, including the fact that some of them were already in utf-8. Run it from folder where your *.lproj directories are placed.

STRING_FILES=$(find . -type f -name '*.strings')
for f in $STRING_FILES; do 
  ENCODING=$(file -I $f)
  if [[ $ENCODING == *"utf-16le"* ]]; then
    iconv -f UTF-16 -t UTF8 $f > $f.1; 
    mv -f $f.1 $f
  fi
done

The idea of it was taken from Yuchen Zhong's answer

Accid Bright
  • 592
  • 5
  • 17
1

I've noticed that SourceTree is not able to diff english localization file only, the others were fine. So it looked like something was wrong in that file only.

I've replaced the english one with some other random Localized.strings file which were SourceTree diffing ok, copied english translations over, commit and voila - any new change was properly showed by SourceTree.

Remember you have to commit and see if it's working since you have to compare fixed one against fixed one.

Viktor Kucera
  • 6,177
  • 4
  • 32
  • 43
0

I found the best way to do this was to use iconv to convert to UTF8, the other stuff does not work for viewing diffs in github.

iconv -f utf-16 -t utf-8 path/to/localization/en.lproj/Localizable.strings > temp.strings
mv temp.strings path/to/localization/en.lproj/Localizable.strings > temp.strings

Then commit and merge your changes. Subsequent diffs will be shown properly.

ihux
  • 164
  • 1
  • 7
0

Follow the instructions on this page https://gist.github.com/asmallteapot/11227602

You don't have to convert your .strings files to UTF-8

Daniel
  • 132
  • 1
  • 12
0

No need for .gitattributes and .gitconfig files in my case!

Simple steps you need to do:

  1. Open currently available .strings file and copy all of it content
  2. Open terminal type nano <path/to/your/file/Localizable.strings> - you can drag and drop file to terminal after typing nano - don't press return yet
  3. Remove file to trash (to save it in case of failure)
  4. Go back to terminal and press return
  5. Paste clipboard content to terminal
  6. Press control+x and y to save the file
  7. Repeat for .strings files in your project
  8. Enjoy diff on your .strings files!
Ivan Besarab
  • 990
  • 7
  • 12