WARNING
Gitblit is apparently no longer actively maintained. As of this writing, the last commit on its master branch was in June 2017. With that state of affairs it is unclear how long it will still be possible to get Gitblit to work inside Gerrit.
Gitblit is based on old libraries; Gerrit uses much newer ones. When running inside Gerrit, Gitblit needs to use the Gerrit versions of libraries they have in common (like JGit or Lucene). The gap is getting larger with each Gerrit release, and there will be a point where it cannot be bridged anymore.
In the long run, this is a dead end.
Gerrit-GitBlit plugin
This is a fork of the official Gerrit-GitBlit plugin, forked originally from master revision 28d2c98.
It integrates GitBlit as a repository browser into Gerrit as a Gerrit plugin.
Pre-built jars (Java 8, before v2.14.171.0 Java 7) are available as releases. Pick one with a version number matching your Gerrit version. Version numbering for this plugin is the Gerrit API version it was built for, followed by the collapsed GitBlit version, followed by the plugin version.So "v2.9.1.162.2" is version 2 of this plugin, integrating GitBlit 1.6.2 into Gerrit 2.9.1.
If you're running Gerrit 2.11 or newer, you might want to check whether the official plugin fulfills your needs. (To find a pre-built official plugin, go to the Gerrit CI server, find the "Plugin-gitblit" job matching your Gerrit version, click the link, and download the jar from "Last Successful Artifacts".)
Motivation
The basic reason for doing this was to adapt the official plugin to work with a modern Gerrit (v2.9 or newer) and a modern GitBlit (v1.6.2 and later v1.7.1). This was done at a time when Gerrit 2.9 and 2.10 were the current Gerrit releases, and the official plugin just didn't work well.
The official plugin was a bit dated by then. Luca Milanesio described the original integration in a slideshow. Basically, this Gerrit-GitBlit plugin depended on a hacked version of Apache Wicket (classloading in UI), and on a hacked version of Apache Rome (classloading in RSS feeder). Additionally, it only worked with a specially built version of GitBlit 1.4.0. In particular, Luca had moved all the static resources in GitBlit into a "/static" subdirectory so that they'd be accessible by the standard Gerrit plugin mechanism, which does handle this directory specially.
This worked more or less, but had a number of problems:
- The official plugin didn't produce branch graphs. That's Gerrit bug 2942.
- It somehow didn't serve the Flash copy-paste helper. (clippy.swf)
- GitBlit 1.4.0 produced diagrams and graphs using the Google charts API, making requests to Google.
- RSS feeds didn't work for me.
- The official plugin set the base path for GitBlit to Gerrit's git directory. It should point somewhere else.
- Using a specially built GitBlit jar hosted at an apparently non-browseable Maven repository at GerritForge was a lock-in that I wanted to avoid. It means there's no reasonably easy path to get bug fixes in GitBlit since this fork of GitBlit was produced. I wanted to have a Gerrit-GitBlit plugin working with the latest standard official release of GitBlit from the standard official GitBlit maven repo.
You might wonder whether the whole approach of including GitBlit as a Gerrit plugin makes sense at all. The basic problem this plugin tries to overcome is the lack of any decent repository browser in Gerrit. While you can make it use GitBlit, gitweb, gitiles or any other external browser, I don't readily see how one would propagate all the view and action permissions defined in Gerrit to such an external browser, be it GitBlit or something else. Luca's integration approach has the benefit that these rights can rather easily be propagated to GitBlit, so if a user cannot see or modify a branch or repository in Gerrit, he also won't be able to see it through this GitBlit plugin.
Still, Gerrit is a git server, and shoving a fully blown down-configured other git server like GitBlit into Gerrit to get a repository browser with a nice UI smells like overkill. I share James Moger's puzzlement over this, but since GitBlit has a very nice UI indeed and works well, it's an easy way to get what I want. True, I'd much prefer having a stripped-down GitBlit component that included only the parts relevant to browsing and viewing repositories, but no such component exists, GitBlit is not modular enough to quickly extract those parts (or I don't know how), and unless GitBlit itself offers such a component, creating one would just create another specially hacked GitBlit fork.
What's changed?
A lot.
Well, maybe not that much. But GitBlit has changed quite bit since 1.4.0; its internal structure is different, and thus the Guice injection setup must be much more complete. Whereas the original plugin was able to get this to work mostly with just wrapping some servlets and setting them up through Guice, one has to do quite a bit more with GitBlit 1.6.x.
- I've fixed the "missing branch graphs": Gerrit bug 2942
- I've made the RSS feed work.
- I've given GitBlit its own base directory to avoid that it creates subdirectories in the git repository directory that don't have anything to do with git repositories.
- I've disabled GitBlit's own plugin mechanism. Two layers of plugins is too confusing, might not work as expected anyway, and in all likelihood is not needed since GitBlit is used only as a repository viewer in this plugin.
- The dependency on GitBlit has been changed from Luca's special GitBlit version to the standard GitBlit 1.6.x distribution.
- The dependencies for Apache Wicket and Apache Rome have been changed to the standard distributions.
- The dependency on the Gerrit API has been changed from a snapshot version to the latest official release.
- Removed all the transitive dependencies from the
pom.xml
. - The whole authentication/user model logic had to be refactored due to GitBlit changes.
- GitBlit 1.6.x still used the dagger injection framework. Since GitBlit 1.7.0 , Guice is used.
- I've introduced a new servlet to serve those static resources from wherever they are in the original standard GitBlit jar. This also serves clippy.swf correctly now.
Additional modifications were due to changes in GitBlit:
- GitBlit 1.6.x/1.7.x uses the flotr2 library to generate charts and graphs. It doesn't make requests to Google anymore. But to get that to work in the plugin, some more URL rewriting was necessary to make the flotr2 static resources be served from within the plugin jar.
- GitBlit 1.6.x switched to the pegdown markdown parser. That caused me some headache because Gerrit versions smaller than 2.11 include a version of pegdown that is too old for GitBlit.
Installation
Download the latest release for your Gerrit version and install
the downloaded jar file as gitblit.jar
in Gerrit.
If remote plugin administration
is enabled in Gerrit, this can be done for instance by doing (assuming you downloaded gitblit-plugin.VERSION.jar
)
ssh YOUR_GERRIT_URL gerrit plugin install - -n gitblit.jar < gitblit-plugin.VERSION.jar
ssh YOUR_GERRIT_URL gerrit plugin reload gitblit
This is a fairly large plugin, adding many classes to the JVM Gerrit runs in. Depending on what kind of JVM you're using, I
cannot exclude the possibility that adding GitBlit to Gerrit might lead to "java.lang.OutOfMemoryError: PermGen space". If you
ever observe this, increase the "PermGen" memory for Gerrit. For the Oracle HotSpot JVM < 8.0, you'd do that by adding the option
container.javaOptions = -XX:MaxPermSize=320m
(or whatever size you deem appropriate) to gerrit.config
. Possibly you
then also might want to increase Gerrit's maximum heap size a bit (that's container.heapLimit
).
See the Gerrit documentation.
As of HotSpot 8.0, this "PermGen space" issue should not occur, and the "-XX:MaxPermSize" option has even been removed from HotSpot. See the Java 8 compatibility guide. The reason is that HotSpot 8.0 stores the class metadata no longer in the Java heap but in native memory, like IBM's J9 VM does.
Configuration
See the built-in documentation, which since version v2.11.162.2 is after installation also available as <Your_Gerrit_URL>/plugins/gitblit/Documentation/ or through the "GitBlit→Documentation" menu item.
Caveats and To-dos
-
I have not gotten around to try out Lucene indexing of Gerrit repositories in GitBlit. Since this is a feature I don't use, I have no plans to do anything about this in case it doesn't work.
-
I run this plugin in a firewalled private network, and it seems to me that the authentication stuff is good enough. I do not know whether it would be good enough for running this on a public network, or whether I goofed somewhere big time. I'm no web security expert and cannot make any guarantees. I strongly suspect that the RSS feed does not honour ref-level visibility restrictions; it only honours repository-level visibility.
-
I do not know how well GitBlit scales. It does not seem to be clusterable: according to its author, James Moger, "Gitblit is heavily filesystem based and does not support clustering." Additionally, he gives "Small workgroups that require centralized repositories." as the target audience. I run this plugin for such a group, and it appears to work fine.
-
In any case, see points 7 and 8 of the
LICENSE
(no guarantees, no warranty, no liability).
Building
I use Eclipse for development with m2e and m2e-apt installed. Make sure m2e-apt is enabled for the project. (It's not really needed to build the plugin with Gitblit 1.7.x, since that uses Guice. It's only needed to build versions of the plugin based on Gitblit 1.6.x.)
To build, run the maven target "package", for instance from the Eclipse IDE right-click the pom.xml file, select "Maven build..." from the
context menu, enter "package" as target and click "Run". This produces a file "gitblit-plugin-VERSION.jar" in the target directory.
Install that in Gerrit as gitblit.jar
. It should end up in $GERRIT_SITE/plugins/gitblit.jar
.
Since I do not know and do not use buck, I have removed the two BUCK
files. This is a pure maven project.
If you need the BUCK files for some reason, check them out
from the official plugin and adapt them to match the pom.xml
.
Alternatives
Some time after I had released my first version of this plugin, the official plugin was updated to work again with Gerrit release 2.11. Internally it's based on a custom-built GitBlit version 1.7.x. You can find that official plugin on the Gerrit CI server. I have never used it, so I have no idea how well it works.
In early May 2015, some of my changes here were merged back into the official plugin, but there are still functional differences, mainly
related to plugin reloading, raw file serving, handling of non-logged-in users, and how gitblit.properties
is loaded and what default
settings are provided by the plugin.
The official versions of this plugin in the Gerrit repo for Gerrit versions smaller than 2.11 are all based on the old GitBlit 1.4.0 and all exhibit the problems mentioned above.