OK, finally I’m ready to present my collaboration/content-sharing tool – ThinGit! ThinGit periodically synchronizes local Git repositories with their remote origins and features automatic conflict resolution by creating timestamped copies of conflicted files. As such, its primary use is as an alternative to DropBox and SparkleShare!

As the name suggests, it is – similarly to SparkleShare – based on Git. To be precise – the idea behind it is identical, so all tutorials for setting up a repository for SparkleShare are also valid for ThinGit.

ThinGit is completely self-contained (requires only Java) and comes in a single JAR file 1.8MB in size. Under the hood it uses JGit (for Git repository handling), JSch (for SSH access), cli-parser (for command-line arguments parsing) and – interestingly – AspectJ. Yes – for the first time ever I actually found a good application for AspectJ. I used it to inject code that sets HTTP proxy for SSH sessions created by JGit (functionality which is unfortunately not exposed by JGit API and it wasn’t possible to set a default proxy using JSch API either). ThinGit was originally a command-line only tool (compare pics 1/2/3) and actually can still be considered command-line in nature because the minimalistic GUI I’ve prepared basically just helps you set the proper command line arguments (and remembers them for future use). To adhere more to industry standards, it also features a tray icon and notifications about repository updates in balloon tips (pic 4) but that’s it – lean and mean, as promised 😉

Now, let me describe briefly the list of parameters:

Paths containing Git repositories to be serviced – this is a list of paths on your local filesystem with Git repositories that you wish to have handled by ThinGit
HTTP proxy host/port/username/password – these parameters specify the HTTP proxy to be used; if host is not set, the others are ignored
Username to be used in case of interactive authentication – CLI-only – specifies the username to be used for remote SSH connections
Ask for password to be used during interactive authentication – CLI-only – makes ThinGit ask for password at startup; this password will be used for all authentication purposes later
Delay between synchronizations (in milliseconds) – Delay between consecutive cycles of synchronization; it’s a matter of personal taste, reasonably can be anything between 10 seconds and 10 minutes; note that if both sides have this delay set to 10 minutes, the worst case delay between side A updates getting propagated to side B is 20 minutes!
Disable graphical subsystem – forces use of CLI; normally ThinGit tries to launch GUI and only if it fails, falls back to CLI
Clone selected repository – this argument takes precedence over -repos; if it’s specified ThinGit will perform a git-clone command on the selected repository; normally you will launch ThinGit once with this parameter set and then clear it and set -repos instead
Target path of cloned repository – target argument of the git-clone command
Cycle once through repositories and exit – don’t loop the execution, process all repositories once and exit
Show configuration dialog – Unused
Set Java look and feel – GUI-only – Sets Java Look and Feel, possible values are windows and gtk; you can also set LAF using Java’s standard -Dswing.defaultlaf= switch. Requires restart!
Start as tray icon only – GUI-only – Starts application without showing the main window

Noteworthy, JGit, and thus ThinGit processes ~/.ssh/config file so it is possible to set up a password-less key-based login to your repository server! In my case, the whole setup was like following: I’m running an Apache server with mod_proxy limiting access by IP and AllowCONNECT set to Yes and SSH with key-based authorization. My ~/.ssh/config contains appropriate entries. My key is password protected so I have to enter the password each time ThinGit starts. I configured proxy first giving as host and 80 as port, then I ran ThinGit with -clone set to (my test repository) and -clone-dest set to C:/tmp/git5. After it completed cloning, I ran it with -clone parameter removed and C:/tmp/git5 added to -repos.

And that was it! Now I have it running on my test repository for 24 hours already and it’s doing nicely so far. It’s doing such a good job replacing my pen-drive that I’m actually going to establish a more permanent repo and hold all my small projects together in there. I was growing tired of creating separate Git repos for each small thing and keeping them without any versioning is also quite bothersome, so I welcome my own new creation 😉

As you can see (pic 5) a repository serviced by ThinGit can still be accessed by regular Git tools (in this case – GitExtensions) allowing for easy history management.

To summarize the rationale and benefits of ThinGit:
1) Self-contained Java-based application – just one small JAR file for every platform (also Windows XP 😉 ) supporting Java SE. It’s by far the smallest application of this kind!
2) Supports HTTP CONNECT proxy – in my experience, the most reliable way of circumventing firewalls (SOCKS proxy are supported using Java’s switch)
3) Command-line and graphical interfaces that map almost 1:1 allowing for execution in environments with or without graphical subsystem.
4) You can use existing Git tools, including Git-based sharing/collaboration applications like SparkleShare in an interchangeable manner (e.g. when you need to access your repository from Android, SparkleShare might be the right choice!)
5) And of course this – part 1, part 2

I recommend ThinGit to those who are concerned with security and for some reasons have trouble running SparkleShare or just like a lean-and-mean solution like ThinGit more. Enjoy!

DOWNLOAD: ThinGit (JAR file inside ZIP)


  • It’s not clear what ThinGit actually does. My advice to you would be to write it before any other technical description, external dependencies, etc.

  • Hi! Hope your app gets a lot of attention. It has a niche on Windows XP where SparkleShare is not targeting. Definitely, we will be trying your app.

Leave a Reply

Your email address will not be published. Required fields are marked *