Git in Four Commands

Git is not a complicated tool for most things. I still find it a little tricky to set up for multiple users, but even that’s pretty easy. It really caters to the use-case where you’re just starting a project, or are the sole developer, but just want to keep track of changes and versions, make branches, etc.

The first major point of git is that everyone has their own copy of the repository. When you commit changes, you commit them to your local copy of the repository. If you are working on a group project, there is a shared resource that can be pushed to and pulled from, but I actually like that it takes an extra command to do that — it forces me to make sure that it’s what I actually want to do. Now, to the bare-bones commands:

  1. git init — Wherever you’re writing your code, type “git init”. It creates an empty repository in that directory (there’s a magical hidden folder “.git” that gets created and knows things).
  2. git status — Git knows which files have changed since you last saved changes, and it will happily tell you which files are new and changed with this command.
  3. git add — When you change files and are at a point where it make sense to save changes to your code (a bug fix, a new feature, etc.), then tell git which files you want to put in this commit with “git add”. If committing a set of changes with git is like shooting a gun, then adding files to be committed is like loading that gun. Git knows which files have changed, but it can make sense to group changed files into different logical commits. For example, if you fix two bugs between commits, you might want to add the changes for each bug fix separately.
  4. git commit — When you have added a bunch of changed files to be committed, now you’re ready to actually commit those changes. Type “git commit -m ‘A short, meaningful summary of the changes that happened.’”

There is a lot more to git, and a million tutorials, that will explain things in more detail, but these are the commands I spend 95% of my time using, and enough to at least get you starting tracking changes for anything and everything. It doesn’t matter very much what version control you use, just use something.

Tagged with:
 

Until recently, I bore the burden of a dirty little secret: I didn’t use unit testing. I don’t know if this has been other students’ experience, but my software engineering course could have been a lot better. Perhaps it’s a topic that requires students to determine their own level of involvement, but particularly, I am irked that these issues were not as developed as they could have been:

  1. Version control – svn, git, something! Anything, really! Just use something!
  2. Unit testing – sure we talked about it, but its utility isn’t clear until you use it in earnest
  3. Documentation – always felt more like a chore than a tool
  4. Issue tracking – Joel on Software said it best: “I was born with only two bug-storing-slots in my brain.”
  5. More best practices – Effective C++ (it’s worth it — get it and read it) alone was worth more than the course was.

I concede that these are things whose utility might be hard to convey to college students who may or may not be working on projects they really believe in. Still, very important.

One of the things I like about documentation is that you can refer to the documentation when uncertain about side-effects, input, etc. of functions and you don’t really feel like reading through code and trying to keep it in your brain-RAM. Not only that, but I usually refer to my own documentation to get an idea of the guarantee that a function was offering, to try to make sure that it’s making those same guarantees after I make changes. Not only this, but articulating functionality crystalizes it’s implications in your mind. When describing how something works to a friend, it often reminds you of issues you hadn’t considered. Writing documentation is the same in this respect.

When working with other people, while it’s nice to be able to talk face-to-face, the issues we think of that need changing go in one ear and out the other for me. Not that it wasn’t a good idea, but my brain-RAM is not infinite. Bugs, features, ideas, issues all get paged out of my head. Write them down instead, which is where issue tracking comes in. Design questions and decisions come out of issues all the time, and the trail of comments and discussion make a nice reference for documentation.

I find that when I’m fixing a bug, the functionality of that chunk of code gets reduced to that particular feature in my mind. So, if when I try using it, if that bug is fixed, then my job is done. But we’ve all experienced unintended side effects, where in fixing one thing, we break another. Having a list of features to check is a step up from trying to remember the things that need to work, but it’s much less than the power of unit testing. I’ve recently been using UnitTest++ for C++ applications, and QUnit from the jQuery people, and have been pleased to thrilled. It allows you to check functionality exhaustively and quickly on a whim. Even the task of writing the tests forces you to define the functional requirements of your code, and I find it helps to clarify a lot.

Version control lets you try crazy new approaches and track changes, isn’t that great? I was helping a friend last semester with some of his code, and he was trying to make code changes with copy, paste, and the undo buffer. In the end, he ended up introducing more bugs into the code than he was fixing. It’s intractable to keep these kinds of code changes in your brain-RAM. Use something, use anything. I have a qualm with svn because it was something I used so rarely, I could never remember how to set it up. Even a barrier as small as that was enough to prevent me from using version control at all. I love git because it’s so easy to set up, I use it for almost anything: from a report (if using LaTeX), to a weekend project, to my thesis. There are tons of tools out there, but just use something.

I’ve been around the block a time or two (or more) with subversion, but until recently I had limited experience with git. Sure, every now and then I’ve used it to check out projects, but not for my personal use.

No longer. And as of right now, I don’t have any intention of using anything but git for personal development.

Last week, I held lecture for parallel programming and I talked about using subversion for versioning, and I began to suspect that something was horribly wrong. Questions started springing up – where does the repository live? Am I calling svnadmin on my own machine? Where do I check out the repository? Though there are answers to these questions, for many things, such a model just doesn’t make sense.

If I’m working on a project that I’m not syncing between several computers, but I just want to have different stable versions and to try different crazy ideas using branches. It mitigates the cost of reverting drastic changes to code.

Use Case: You’re showing someone your code, and want to show off a neat feature you’ve made, or a problem you’re encountering, something about the project, invariably you’ve run into a problem where it doesn’t compile at the moment. You type furiously, trying to find and undo the most recent changes, but to no avail – there is no hope of getting it to compile in the 5 minutes you have someone’s attention. Enter version control. Revert to the last working copy and victory is yours.

In fact, just today I was asked if I could pull up some code I had been working on to show to a professor. Unfortunately at the moment it wasn’t compiling but was able to switch versions in 20 seconds and show off some very recent work from earlier in the day, thus saving face.

Use Case: You’ve got some crazy idea for an implementation you’d like to try out, but are worried about reverting back all the massive changes you’ll have to make in the code. Worry not! Create a new branch and feel free to change your code in every way you can think of and not lose other branches under development.

Use Case: You’ve got multiple versions of code each implementing the same basic algorithm but with different mechanisms, techniques, etc. and have to turn it in as part of a project. Just archive the whole directory (in a tarball or zip) and the user who unpacks it has access to every version your code has been in. Each branch, each stage of development. And very light-weight to boot.

I can’t speak for others, but I will be using git for the foreseeable future as it’s incredibly easy to use and alleviates many of the problems I encounter regularly with development.

Tagged with: