Fork us on GitHub

TIP: Using Git for Codename One Projects

I didn't write about this before because I considered it a bit too simple, but there is nuance
TIP: Using Git for Codename One Projects

TIP: Using Git for Codename One Projects

I wrote in the past about importing a Codename One demo from github but I left the whole working with git as an open subject. Mostly because I considered it a bit out of scope for the discussion. I have a section in the free online course about the anatomy of a Codename One application which I completely forgot to upload until I wrote this!

If you want to understand more, I strongly suggest watching that as it explains a lot of the "why" and "how" logic of Codename One project structures. It explains the purpose of every file you see in the project…​

The Right Gitignore

We spent yesterday migrating our internal SVN repository (yes we still used SVN internally) to git. The reason we didn’t do it before was historic. We have a 15gb repository for Codename One that includes a lot of history and junk. Git doesn’t work well with large repositories and splitting up the whole thing effectively means discarding history.

We made some attempts at migrating in the past but the scripts would generally fail after 2-3 days of continuous work…​ So we split up the repositories to smaller ones and made a clean break. While doing that we wrote a lot of gitignore files and this made me think a bit about the whole thing. I think there is a lot of nuance in setting up the right gitignore file and there are a few interesting tradeoffs we should consider.

When we first started committing to git we used something like this for netbeans projects:

*.jar
nbproject/private/
build/
dist/
lib/CodenameOne_SRC.zip

Removing the jars, build, private folder etc. makes a lot of sense but there are a few nuances that are missing here…​

cn1lib’s

You will notice we excluded the jars which are stored under lib and we exclude the Codename One source zip. But I didn’t exclude cn1libs…​ That was an omission since the original project we committed didn’t have cn1libs. But should we commit a binary file to git?

I don’t know. Generally git isn’t very good with binaries but cn1libs make sense. In another project that did have a cn1lib I did this:

*.jar
nbproject/private/
build/
dist/
lib/CodenameOne_SRC.zip
lib/impl/
native/internal_tmp/

The important lines are lib/impl/ and native/internal_tmp/. Technically cn1libs are just zips. When you do a refresh libs they unzip into the right directories under lib/impl and native/internal_tmp. By excluding these directories we can remove duplicates that can result in conflicts.

I’m not sure if committing the cn1libs is a good choice. It’s something i’m still conflicted about.

Resource Files

I’m generally in favor of committing the res file and it’s committed in the git ignore files above. The res file is at risk of corruption and in that case having a history we can refer to matters a lot.

But the resource file is a bit of a problematic file. As a binary file if we have a team working with it the conflicts can be a major blocker. This was far worse with the old GUI builder, that was one of the big motivations of moving into the new GUI builder which works better for teams.

Still, if you want to keep an eye of every change in the resource file you can switch on the FileXML Team Mode which should be on by default. This mode creates a file hierarchy under the res directory to match the res file you opened. E.g. if you have a file named src/theme.res it will create a matching res/theme.xml and also nest all the images and resources you use in the res directory.

That’s very useful as you can edit the files directly and keep track of every file in git. However, this has two big drawbacks:

  • It’s flaky - while this mode works it never reached the stability of the regular res file mode

  • It conflicts - the simulator/device are oblivious to this mode. So if you fetch an update you also need to update the res file and you might still have conflicts related to that file

Ultimately both of these issues shouldn’t be a deal breaker. Even though this mode is a bit flaky it’s better than the alternative as you can literally "see" the content of the resource file. You can easily revert and reapply your changes to the res file when merging from git, it’s tedious but again not a deal breaker.

Eclipse Version

Building on the gitignore we have for NetBeans the eclipse version should look like this:

.DS_Store
*.jar
build/
dist/
lib/impl/
native/internal_tmp/
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*.zip
*~.nib
local.properties
.settings/
.loadpath
.recommenders
.externalToolBuilders/
*.launch
*.pydevproject
.cproject
.factorypath
.buildpath
.project
.classpath

IntelliJ/IDEA

.DS_Store
*.jar
build/
dist/
lib/impl/
native/internal_tmp/
*.zip
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/gradle.xml
.idea/**/libraries
*.iws
/out/
atlassian-ide-plugin.xml

Finally

This is by no means the final version of this. These sort of files tend to change over time as more functionality (e.g. Kotlin support) makes its way into Codename One or the respective IDE’s. This can also be impacted by your OS or IDE plugin. Notice I excluded .DS_Store which is a file Mac OS sometimes creates but I didn’t exclude Thumbs.db because I don’t use Windows as much.

Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.