loading...

Git Gud at git

nichartley profile image Nic Hartley ・3 min read

Show of hands, everyone, who knows git?

Not just the standard git pull / git commit / git push arcanery that you go through to magically make your changes public, who actually understands git? Who here understands its internal tree model, the thing that makes it work so well?

If your hand is still up, you can feel free to skip this post, or pop over to the source and help implement more features. You may want to hold off for a little while before you contribute, though; I'm porting it from WASM to JavaScript.

If you don't know how it works, though, can I recommend something I made? It's called Git Gud.

What is it?

Git Gud is a web-based Git simulator. It shows you the git tree visually, and you can run commands to show you what they do to the tree. You start out with an initial commit:

initial state

You'll notice it's labeled "c0". That's the commit ID. Because we don't have any actual files to track -- that's for a much later version -- we don't have anything to hash, and on our initial build, we just ordered commits sequentially. The first, automatically generated commit is "c0", the second is "c1", and so on. Speaking of the second commit, click in the bottom area and try typing:

commit

You'll see another commit get added:

first commit

Just like in Git, you can checkout individual commits:

checkout c0

checked out

You can also make a new branch with branch, check it out with checkout b1, commit on it, merge it back in, etc. For example, enter this sequence of commands:

commit
checkout c0
branch
checkout b1
commit
checkout b0
merge

and you'll get this:

done

If you want to reset, well, there's no git command for that, but we've repurposed init:

initted

Why?

If you look at the commit history for Git Gud, you'll notice a massive spike in development over the course of a weekend. That weekend was BrickHack, RIT's annual hackathon. It was an interesting experience, and a great way to get a prototype up and running.

It did introduce some issues, though. The code isn't too great, since we didn't have a chance to really think through issues in just 24 hours. We wrote it in WebAssembly rather than the pure JavaScript that would have been less effort to develop and debug, because one of the team members only knew C++ and wasn't sure he could learn JavaScript in the few days well enough in the few days before the hackathon1.

1: As it turns out, he was able to learn it in an hour or so during the hackathon, at least well enough to edit some drawing code. Oops. Probably could have done that better, then.

Next steps

Right now, Git Gud pretty barebones, as you'll definitely notice if you try it. There are quite a few features we want to implement, most of which boil down to working more like the real git. For example:

  • If you type git at the beginning of the line (say, out of habit from using real git), delete it from the input rather than breaking
  • Informative (aka any, in some cases) error messages when you do something wrong
  • Rebasing
  • Commit messages
  • Branches with names
  • Parsing flags like -b on checkout
  • File changes, rather than just abstract 'commits'
  • More themes. Amber on black is pretty, but it'd be nice (and not too hard, really) to offer multiple colors.

Got any other ideas? Anything you want me to know as I develop it more? Either raise an issue, or comment on this post.

Posted on Feb 21 '19 by:

nichartley profile

Nic Hartley

@nichartley

I'm a programmer who likes games, and wants to make games for a living. At the same time, there are some really cool non-game things I want to work on -- especially if they use C or C++.

Discussion

markdown guide
 

I love this! As you add support for more of Git's features, this will become very useful. Not to mention, it's fun! I'd like to be able to refer people to this as a training tool someday.

I'd also like to see this gain some ability to work with "push/pull" to drive home the point of remote vs. local.

 

Push/pull is definitely on the table, but maybe a little further down. A bunch of the code is centered around there being just one tree with just one head, one set of branches, etc., and it'd take a decently big refactor to make it more abstracted. It's definitely not impossible, though, and it'll come eventually.

 

You guys could take a look at learngitbranching.js.org/. I have used this to learn a couple of years ago. It's quite mature

 

Looks cool! I like Git Gud better, personally; it has a much cleaner look, but there are definitely some lessons to learn from that. It also gives me some ideas for how to implement more difficult commands like cherry-pick. Thanks!

 

It looks interesting, but I'm put off by the way it's themed to look like an old Mac, and that it's completely non-obvious that you can scroll bits of it (I suppose that is keeping the Mac philosophy of having an unintuitive UI, but still...)

 

I was going to comment the same! Learned a lot with learngitbranching when I was learning git about 4 years ago! I always recommend it.

For the post, it's still and very interesting project, congrats to the authors!

 

This really awesome stuff! I spent a whole couple hours this morning trying to learn git beyond just add+commit+push, and I'm still confused by it all! Really helpful and looking forward to when you add more features!

 

Neat! I've had a similar idea kicking around for a few years to illustrate how rebasing works with animation, but haven't got around to implementing it.

An interesting approach might be a live visualisation in a browser of an actual repository on disk, since that would mean you can focus on the visualisation without having to emulate git's command line.

 

While that'd certainly be cool, it'd be much more work. This way I can emulate the tree in very little memory and without needing to access the filesystem at all, which can be difficult.

I do also plan to add rebase, actually, to Git Gud -- I'm just swamped by work right now. Being a student can be tough, haha.

Plus, there's always git log --graph --all or gitk --all :)

 

This is a really cool idea, and a Git playground would be useful for the after-school CS program I'm part of. I'm also kind of in awe that you're using C++ for this.

But I have to say that the way branches are modeled here doesn't really line up with how I've come to see them. While it can be sometimes useful to picture them as "lanes," branching in Git only made sense to me when I started picturing them as just pointers to a commit.

(If commits are lanes, what does it look like when a commit is part of multiple branches?)

It's deceptively simple, and for a long time I didn't get that I didn't get it. I had come to Git from Subversion, where branches actually are lanes. Eventually I read Think Like a Git and Git's model finally clicked. Suddenly I was able to branch, merge, cherry-pick and rebase with zero surprises.

It boils down to this: Git has commits, which are full snapshots, and pointers to commits, which give you a way to name them. During a new commit, tags (one type of pointer) stay on the previous commit, and branches (the other kind of pointer) may move to the new one. Only one actually does -- and git calls that the "checked out" branch.

 

Yup, branches are pointers to commits, but there are two issues with drawing them like that:

  1. It makes it hard to tell which commits are part of which branches (you need to manually follow them back from the head, and even then it's hard to tell where one branch 'splits' from another)
  2. It makes it much harder to render.

Honestly, the latter was the biggest thing; we tried to get labels pointing at the branch head, but because of all the edge cases it was surprisingly hard to get it happening without making something look weird.

 

I love it! It illustrates how git works, and especially for noobs like me, I'm getting a kind of close-to-actual representation that you can't see elsewhere (or am I just not searching too far?) Hahaha!

 

I love this idea! This would be an excellent playground for Git noobs, especially those that come from a more traditional VCS, like SVN. Great job!

 
 

Awesome stuff! Am so gonna use this on my next Git workshop/class!

 

Did you play "Hollow Knight"? Git gud is a popular term there. I played 💯 hours and still cannot best the boss.

 

It's popular across a lot of gaming, not just Hollow Knight; the gaming term is where we got the inspiration for the name.