[anjuta-devel] Git plugin libgit2 porting status update
- From: James Liggett <jrliggett cox net>
- To: Anjuta Mailing List <anjuta-devel-list gnome org>
- Subject: [anjuta-devel] Git plugin libgit2 porting status update
- Date: Wed, 07 Aug 2013 21:25:33 -0700
Hi Everyone,
This is a pretty long message, so please bear with me here... :-)
For the past few weeks I've been working on the initial phases of my
plans to port the git plugin to the libgit2 library. Unfortunately, my
experiences have made me think that moving to libgit2 may be more
trouble than it's worth. This certainly isn't the conclusion I was
hoping for, and I'm sure many of you will be disappointed as well. There
are three major reasons I have for to this conclusion:
1. Libgit2 is much too low-level for our needs; even implementing simple
things like status are more complicated than they look
2. Many features we need are missing, especially things that depend on
merge, including frequently-used features like pull.
3. Libgit2 needs to be compiled with special options to work well with
our multithreaded environment. These issues may cause problems for our
users, as they would be responsible for making sure their libgit2 is
compiled with the right options.
After spending over a month working with libgit2, I think that it works
with git at a level much lower than we really need. I started with what
I thought would be a relatively simple, yet non-trivial feature in the
git plugin: status. As it is, status is one of our more complicated
commands with a lot of regular expressions and other string handling. At
only 130 lines of code, including GObject boilerplate but excluding the
header file, the libgit2 based status command is pleasantly concise.
But, things were about to get more complicated. I gave this new,
lean-and-mean status command a quick test, only to discover that
libgit2's internal index cache isn't updated after a commit, so that
files I just committed would show up as modified in both the index and
the working tree in the status view, even though they weren't, per git
status command output. Libgit2 keeps an in-memory cache of the index,
but you have to update it manually by calling an API that rereads the
index from disk. But, if you don't do these calls at the right time,
libgit2 will crash when you ask it for status.
Long story short, to get stable and correct status output, I had to
implement a second object to watch for index changes, then read the
index. To get the status pane view and the file manager working, I have
the plugin listen to a signal from this object that gets emitted after
the index is read, and in response to the signal I have the plugin
refresh the status view and emit status-changed for the file manager.
While getting status from command line git certainly presented its own
set of challenges, the additional engineering work needed to make
libgit2 work in this case made it surprisingly more complicated than
what we had originally.
Status wouldn't be the only instance where we would need to go well
beyond the usual scope of a version control plugin. If you take a look
at gitg's source code, you'll see that they're effectively rewriting git
commit almost from the ground up, where they even handle pre- and
post-commit hooks. See
https://git.gnome.org/browse/gitg/tree/libgitg/gitg-stage.vala#n315
In addition to the added complexity that libgit2 introduces, it
currently lacks a few features we need. Among these:
- It doesn't show conflicted status entries properly. They show up as
removed in the index. Per
https://github.com/libgit2/libgit2sharp/issues/335 it shouldn't even
show them at all.
- It doesn't support merges of any kind at this point. Merges are the
engine behind a lot of features in git, so we also lose things like
pull, rebase, applying stashes, reverting commits, and, obviously, merge.
Finally, our choice to use libgit2 could put an additional burden on our
users. For libgit2 to work correctly in a multithreaded application, you
must ensure that it is complied with a special thread safe option, which
is off by default. Users will have to make sure to include this option
if they compile libgit2 from source.
We probably can't assume that distro packages will be compiled with this
option. As a result, many of our users would probably have to compile
themselves, and I'm betting that most won't know they need this option.
If libgit2 isn't compiled with it, I get a lot of crashes in various
places. Effectively, libgit2 could be a big hassle for our users and a
support headache for us.
After seeing how simple the new status command was, I really wanted
libgit2 to work. Sadly, for the reasons I outline above, I think that
moving to libgit2 now would require a lot more work just to get to the
same place we already are by using command line git. At this point I'm
going to put this work on hold. From time to time I want to reevaluate
libgit2 to see if it becomes more suitable for us. I'm keeping the
current version of the work in progress port in a branch named
libit2-glib if anyone wants to have a look at it.
Thanks,
James
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]