Eugene Verichev
Eugene Verichev

Reputation: 355

Converting file (tracked with Git) from Java to Kotlin in Android Studio

A conversion from Java to Kotlin in Android Studio 2.3.2 (in 3.0 the same behaviour) creates a new file and deletes previous. So Git doesn't know anything about this conversion. And the git history doesn't save. In Intellij Idea everything's fine. IDE just renames file and git saves the history. How can do the same in Android Studio.

Upvotes: 29

Views: 5571

Answers (5)

DA_123
DA_123

Reputation: 385

Android Studio now has an option: Extra commit for java > kt renames which is enabled by default and fixes git blame. But this creates an invalid commit in the history.

If this change is rebased, then you keep git blame, but lose git bisect, and the opposite is true if you squash merge.

I've created a small (MIT) gradle script and instructions to get the best of both worlds (TL;DR: perform a rename, and in the same commit, flag to the compiler that the renamed .kt file should be run via javac):

https://github.com/ankidroid/Anki-Android/blob/bffd3c60c00649cdc75f35293a85f7e1ef064b53/docs/kotlin-migration.md https://github.com/ankidroid/Anki-Android/blob/1ee5f65b87a8fe544193d928d64dd8395513c9f0/AnkiDroid/kotlinMigration.gradle

The above could further be productionized in an IntelliJ plugin.

Upvotes: 1

Hay
Hay

Reputation: 2281

In case this might help a future reader:

If you use the Git commit dialog integrated with IntelliJ (Commit via Ctrl+K), there is a checkbox on the right in recent versions: ☑ Extra commit for .java > .kt renames

Submitting the dialog this way will create two commits, the first one being just .java files renamed into .kt files with no content changes. This helps Git track the content.

Upvotes: 13

Giorgos Kylafas
Giorgos Kylafas

Reputation: 2381

As mentioned in the other answers, git tracks the contents of the file, not its renames. When git log is run with --follow option, it shows history beyond renames, however it considers a file to be renamed only if the previous and current file contents have a similarity index of 50% or more, i.e. less than half the lines of the file have changed.

For this case, where most of the lines have changed, you may set a lower bar for the similarity index using the -M option:

git log -M20% --follow -- /path/to/file

Depending on the case, you may need to go even lower than 20%.

Upvotes: 4

Ilya
Ilya

Reputation: 23144

Git guesses renames from added/removed file pairs, but only if these files are close enough, i.e. if the file was renamed with no or small amount of changes.

When you apply java-to-kotlin conversion usually every line of a file changes, so that git cannot find that these old and new files somehow relate to each other.

You can use the following two-stage approach instead:

  • just change the extension of .java file to .kt and commit it;
  • rename it back, apply the conversion and commit the modified .kt file.

Upvotes: 30

adzenith
adzenith

Reputation: 777

Git doesn't actually track renames directly; it infers them based on file add/delete pairs. I assume that Idea is running a git add when it renames, whereas Android Studio is just deleting the old files. Try running git add yourself on the new files and a git rm on the old files and Git should show them as renames.

Upvotes: 0

Related Questions