Wednesday, June 3, 2015

Gitlab Wish List

Gitlab Wish List

I started using gitlab at work. I looked at several git web guis, but I ended up liking gitlab the best. I'm using the community edition, and it's hosted on a machine on our internal network.

If you're not familiar with it, it's a lot like github, except that it is open source, and you can run it locally on your own hardware. The company behind it also sells an Enterprise Edition. And like github, you can host your repos at gitlab.com. They even offer private repos for free.

But to me, being able to host it locally is its biggest selling point over gitlab. And it's hard to beat the price tag of free.

So if you need something like that, I do recommend gitlab, and it is what I'm using for that purpose.

This post is mainly going to be about the weird way I'm using gitlab, and about the features I wish it had. Don't take this to mean I don't like gitlab, it is what I'm using after all.

Keep in mind that gitlab has very frequent updates. If you run into this post a a year from now, it's possible none of my complaints will be valid.

My Setup

Several projects are normal git projects, but one project in particular, which is also the largest project, is not.

That project officially lives in svn.  I have a git-svn clone of it with a carefully created configuration. There's a cronjob that every five minutes does 'git svn fetch' and 'git push gitlab'. There's a special user, named svnbot, that the pushes are done under, so that they don't all show up as my user account under activity.

I think my setup is unusual in that I'm mirroring svn on gitlab on a continue basis, instead of doing a one time import and using only git from then on.

The Workflow

Many users checkout from svn, and commit with svn, and don't need to care about gitlab.

Others clone from gitlab, make their changes, and then 'git svn dcommit' back to svn. I have a script, hosted on our gitlab, that runs 'git-config' a whole bunch of times in order to configure git-svn the same way that svnbot's is configured, so that this can actually work. (It also takes care of the authors file and a few other things.)

So after doing a clone, there's a script you have to run before you can 'git svn dcommit', but after that things a pretty normal. You can fetch new changes with either 'git fetch' or 'git svn fetch'.

Topic Branches and Merge Requests

Things get interesting once people start using topic branches. Now people can submit Merge Requests in gitlab (which are like Pull Requests on github), and get their code reviewed before they commit it back to svn.

Now the flow is something like
  • Pull for gitlab
  • Create new topic branch
  • Push topic branch to gitlab
  • Iterate on topic branch for a while
  • Submit MR
  • Possibly push new commits in response to feedback from MR
  • Optionally rebase
  • git-svn dcommit

One Way

My svn to gitlab syncing only goes in one direction. Because of that, Merge Requests should be upvoted but not Merged.

As an aside, the upvote feature on Merge Requests was really hard to discover.

There's a lot of branches from svn. In particular, all tags show up as branches. So I've protected the most common branches so that only svnbot can push to them. But there's no mass protect button, so most branches that should be protected are not.

Problems

Who Got Notified?

I just pushed a new commit to a Merge Request, did the assignee get notified? I just commented on a commit, did the author get notified, or do I need to tell them to look at it?

I'm never certain who got notified by what I just did. I wish there was a way to just see that information somewhere. That way I could be sure.

In most cases, the answer seems to be that they did get notified. It's just the uncertainty that bothers me.

SVN Revisions

Svn has its own revision numbers. git-svn puts these numbers, along with the branch url, in a sort of header at the end of the commit log of every commit.

Now, I don't expect gitlab to have special support for git-svn. But I do expect its search feature to search commit logs. If it did support that feature, then I could search by svn revision, since the svn revisions happen to be in the logs.

Sadly, it doesn't yet support that feature.

Performance

Gitlab's performance is ok most of the time. Since it's on our own hardware, most performance problems are our own fault and not gitlab's.

But it does get bogged down on some of the larger files I sometimes have to deal with.

One of the git repos is an import of the Asterisk source code. These guys used a one file per module approach for a long time, and a few of their files got way out of hand. The biggest offender is chan_sip.c, which is around 80,000 lines long. (I'm not kidding.)

When I first started using gitlab, it would fail to load that file, and it would time out with a 500 Internal Server Error. But the newer version we're currently running is a bit better and can load it, but not quickly.

One could argue that a 80,000 line .c file is unreasonable. And one might be right, but I'm not in a position to fix it, I just need to deal with it, and so do the tools I use.

Besides, vim and the cli git command deal with it just fine. In fact, with the exception of the blame command, git is always unreasonably fast. This causes me to expect any GUI on top of it to be just as fast.

Sharing Links

One nice thing about using gitlab is that it gives me a way to link to code. It even has a #linenumber in urls, so I can link someone to a specific line of code.

It could be better though. I can't link to a range of lines, and sometimes it fails to scroll to the linked to line. It could probably do a better job of highlighting the linked to line.

I can link to particular lines in a diff. Well, I think that feature actually broke for a while, and then they fixed it.

One thing I can't do is generate a diff of a subtree. I want to diff a...b of /foo/bar/, but I can only diff a...b of /.

Diffs

I really enjoy having syntax highlighted diffs. The ability to link to and to comment on specific lines is great. I can comment on both Merge Requests, and on specific commits. So I can still tell someone "this line here is wrong!" even if they skipped code review.

Besides using it as a place to pull from and push to (and anyone can do that), the Diff view is the main feature is use. (Often in conjunction with Merge Requests).

But I do have some complaints.

The word-diff feature isn't very smart. If two lines in a row are changed, that shows up as two minus lines and two plus lines. That seems to be enough to default the per word diff highlighting, it doesn't activate. Which is a shame, because when it works it's a very useful feature.

It might be nice to have an option for "context" diffs, the ones that are like unified but have "!" in addition to "+" and "-". "!" means the line was modified. (Unified just shows it being removed and the new modified line being added.) I normally prefer Unified, but I wonder if with word diff support, context diffs might be nicer than unified, at least sometimes.

There's a "..." in the margin to show more context on the diff. Unfortunately, it doesn't let you control whether you want more from above or below the "...". There's also no way to say "just show me the whole file!".

There's a git TUI named "tig" that lets you increase the number of context lines (or decrease it) with the [ and ] keys. It would be neat if gitlab had a way to do that, although clicking the "..." is often closer to what I want. ('tig' is actually pretty cool, and I would encourage the gitlab people to use it and steal ideas from it where it makes sense.)

The hunk line is displayed way too lightly. That line displays the starting and ending line numbers of before and after the diff, which isn't needed in a GUI like this. But it also displays the enclosing function, which is very useful information.

It's stupid to make it too light to read. Either hide it completely, or make it readable. And do the second of those, because I want to see it.

The diff view doesn't respect the theme.

It would be awesome if it could do filetype highlighting and diff syntax highlighting at the same time. Github does that now, so hopefully it's just a matter of time.

It would be even more awesome if it could do code within code within diff highlighting. I might have some SQL inside of some PHP, and I might have added a new column to the SELECT list, and there might already be 10 columns selected, so I really need the word diff highlighting.

Blame

One useful command is 'git blame', and gitlab has support for a blame view of files in its interface. What this does is, for every line in the, it shows you who last touched that line and what commit that was.

While the name implies it's for assigning blame, really it's for looking at the commit that introduced a given change in it's entirety.  Sometimes it does lead to asking the author some questions though.

Gitlab used to have a bug where the blame view would always show the blame for the master branch, regardless of what revision you were on. This was really confusing. Fixing this bug is currently my only contribution for gitlab. (It was a one-liner.)

I do wish that gitlab supported a more advanced Blame view though. Often the first commit isn't the one that introduced a line, and often that's the one you're after. So I usually have to dig multiple commits and do multiple blames to fine what I'm after.

Things like ignoring white space and some of the other options git supports would be a start.

Just having a link is very useful, so that's already a good start.

But I feel like this a place they could innovate. Some kind of onion-skin thing, like what's used for animation packages? I don't know.

Cherry-picking Management

At least one of the git web GUIs I ran into has support for Cherry-picking. I don't remember exactly what it supported, but I do have an idea of the features I would want.

So, the idea is bug fixes get committed to your development branch, but then need to be cherry-picked back to your release branch or branches. You can't merge because that would bring all dev changes to your release branch, and that would be bad.

Git itself doesn't really track cherry-picks though. This is unlike svn, who's mergeinfo property does track cherry picks.

Svn can list revisions available for cherry-picking (which it calls merging) with the 'svn mergeinfo' command. That same command can list revisions that have been cherry-picked.

I don't have much experience using the git-cherry-pick command. I know it has the "-x" option, which strangely used to by the default but isn't anymore. There's also 'git cherry' and 'git patch-id'.

Given two branches with a common ancestor, I want gitlab to be able to display commits available for cherry-picking, commits already cherry-picked, and commits that have been manually excluded from cherry-picking. 

Then I want to be able to mark commits as already cherry-picked, or "not going back". Then I want to be able to see the remaining list.

Being able to cherry-pick from inside of gitlab (a Cherry-Pick Request could be a special kind of Merge Request) would be nice too. And picking up on cherry picks done outside of gitlab automatically would also be nice. But those features aren't as important to me. It's the keeping the list of available cherry-picks that I consider most important. 


Summary of Complaints/Wish List

  • No way to tell who got notified when you comment, commit, etc
  • There's no way to Close a Merge Request and indicate that it was Accepted, any closed MRs that were not merged show in Red as if they were rejected
  • No way to protect branches in bulk
  • You can't search by commit log message, which means you can't search by svn revision
  • Diff highlighting: word diff sometimes doesn't work
  • Diff highlighting: it would be great if it could do code syntax highlighting and diff syntax highlighting at the same time
  • Performance sucks on very large files or very large diffs
  • The "..." that expands a diff doesn't let you choose up or down
  • For some reason, the file viewer is themed, but the diff viewer doesn't respect the theme. But the diff viewer is the main one I use!
  • The @@ hunk line in diffs is displayed too lightly, it's too hard to read, but contains useful info like the enclosing function
  • Can't diff a subpath
  • Better Blame
  • Cherrypick tracking/management