A Git Primer Fit for Linus Himself

by Mike Zazaian at 2009-08-10 20:12:47 UTC in versioning

a quick A to Z primer on how to effectively use the enormously popular git version control system

4 comments no links ["

So Git pretty much took over the world of version control (or supply chain, depending on your perspective) management thanks github and the wonderful services that they provide. I used to use bazaar myself, because I just need to go against the grain that much, and because it is a really wonderful versioning system, but git became far too convenient to ignore, what with pretty much every application in the Rails universe tailored to utilize or accommodate it in some fashion.

\n\n

So, like any good drone, I begrudgingly switched over to Git for a couple of gems I was building, and admittedly haven't looked back since. There really is whole hell of a lot here in terms of articles and blogs, what with gitready covering only git topics and several other blogs of the same or similar ilk. With that in mind I'm not going to try to cover every topic ever in the history of git, but what I will do is provide you with a robust foundation for just basic usage of the system, some shortcuts, some workarounds for issues from my personal experiences, and a some general wisdom and best practices.

\n\n

That said, let's get started.

\n\n

installation

\n\n

If you're on an ubuntu/debian based system, you can install it like this:

\n", nil, "
\n
user@domain$ sudo aptitude update && sudo aptitude install git
\n
\n", nil, "

Pretty complicated, right? Gotta love aptitude, that sweet beast of package managers. If you're not fortunate enough to have aptitude, or yum, or whatever package manager you're using at your fingertips like this, you can consult the git download page and they'll set you up all nice and installationey-like.

\n\n

~/.gitconfig

\n\n

Okay, so that's easy enough. Now we've got the all-powerful git scm/vcs on our system and we're ready to rock.

\n\n

One of the things that you'll notice right off the bat from looking at the manual files is that git tends not to use shorthand for any of its commands as in Bazaar or Subversion. Whereas a commit in Bazaar would have been something like:

\n", nil, "
\n
user@domain$ bzr ci -m "this is my incredible commit"
\n
\n", nil, "

Git commits have to look like this out of the box:

\n", nil, "
\n
user@domain$ git commit -m "i had to type five extra letters but still commited my changes"
\n
\n", nil, "

I mean, yeah, it's only five letters, but coming from another vcs it feels like alien terrain. Plus, over thousands of commits, those extra letters start to add up and it's just wasted time.

\n\n

It's an easy enough fix though, all you have to do is add the following lines to the ~/.gitconfig file in your user directory:

\n", nil, "
\n
[user]\n  name = Your Name\n  email = address@domain.com\n[alias]\n  st = status\n  di = diff\n  co = checkout\n  ci = commit\n  br = branch\n  sta = stash
\n
\n", nil, "

For laymen, the ~/ just indicates your /home/user directory on a nix-based system, not sure where it would be on Windows, though (although I hear that Windows 7 is adapating a more nix-like structure).

\n\n

But I digress -- so yeah, just add those lines, replacing \"Your Name\" and the bogus email with your own info, and you're ready to roll. Now you can use the git ci command to commit, co to checkout, et cetera, et cetera.

\n\n

I should also note that this is a tip I picked up from Jonathan Rockway's Git Merging by Example which is a very useful read indeed.

\n\n

setting up a git repository for your rails app

\n\n

So now that you've got git installed and configured (if you can even call it configured -- supplemented, really), you're ready get your Rails or whatever app ready to go. So you just go to the root directory of your app and setup an empty git repository.

\n", nil, "
\n
user@domain$ cd path/to/my_app\nuser@domain$ git init
\n
\n", nil, "

So that's easy, enough. But I bet 40% of you jumped the gun and did a git add . to add all of your app files to the repository. Which is fine, but what if you've got one of your personal passwords stored in a plugin config file somewhere, or if you've got a log file that's eight times the size of the entire app. Well, that's where .gitignore comes into play.

\n\n

.gitignore

\n\n

As the name suggests, .gitignore is just a file with a list of files and directories, line-by-line from the directory where you did the git init. You'll have to create the file as git doesn't automatically generate one. Here's a good .gitignore file to use as a starting point:

\n", nil, "
\n
#~/path/to/my_app/.gitignore\n\nlog/*.log\ntmp/**/*\ndoc/api\ndoc/app\nlog/*.pid\nlog/call_*\ndb/schema.rb\ndb/*.bkp\n.DS_Store\n*.swp\n*~\nindex/**/*\nconfig/database.yml
\n
\n", nil, "

It's also a really good idea to add any files in your my_app/config directory or anywhere else in your app that might contain personal information such as passwords, or might potentially grow to be enormous and unwieldy.

\n\n

Now that you've got your .gitignore set-up, we're ready to add our application files and create the initial commit. Just make sure that you're still in the root directory of your application:

\n", nil, "
\n
user@domain$ git add .\nuser@domain$ git ci -m "The instantiation of greatness."
\n
\n", nil, "

After you do that you'll see a whole bunch of modes created, one for every file in your application. Something like:

\n", nil, "
\n
Created initial commit 3a3d7ec: initial\n 129 files changed, 32544 insertions(+), 0 deletions(-)\n create mode 100644 README\n create mode 100644 Rakefile\n create mode 100644 app/controllers/application_controller.rb\n create mode 100644 app/controllers/sessions_controller.rb\n create mode 100644 app/controllers/stories_controller.rb\n create mode 100644 app/controllers/tags_controller.rb\n create mode 100644 app/controllers/users_controller.rb\n create mode 100644 app/controllers/votes_controller.rb\n ...
\n
\n", nil, "

And, voila, you've commited your application files to your new git repository. If you make any changes, all you have to do to commit them is just reiterate:

\n", nil, "
\n
user@domain$ git add .\nuser@domain$ git ci -m "Add a whole bunch of features."
\n
\n", nil, "

That's it. Nothing can stop you now.

\n\n

some basics

\n\n

Okay, so we already know how to commit and add and initialize, and you can learn the basics of branching and checking out in that article I referenced earlier, which in all fairness covers the basic needs of most users. That said, there are a few commands that will come in handy for your gitting:

\n\n

git st or git status are useful for seeing which branch you're on, and the states of the respective files that you're working with on that branch.

\n\n

git di or git diff, called without any parameters, will perform a diff between the current state of your files and the previous commit. You can also call it with git di <commit_id> <commit_id> to perform a diff on any two commits.

\n\n

Remember, you can always see the full manual for any of these commands by calling **git --help\" from the command line.

\n\n

file management

\n\n

It's also a very good to get in the habit of using git to move, list and delete files within your git repository. This helps to ensure that your repository is tracking only the files that actually exist in your development environment, and none that you've moved or deleted. This will save you a lot of hassle down the line.

\n\n

The basics are pretty much the same if you have any *nix terminal experience ls becomes git ls-files, mv becomes git mv, rm becomes git rm. Most of the arguments are the same -- just check the respective help files if you have any particular questions about an argument.

\n\n

The only real exception here is that there is no command for copying files in git. You'll have to perform something like:

\n", nil, "
\n
user@domain$ cp file1 file2\nuser@domain$ git add file2
\n
\n", nil, "

Which isn't really a terrible workaround. It's also worth noting that you probably should, from time-to-time (or obsessively, like I do), just type ls in your terminal to get a list of the files in a given directory, then compare that to the results of git ls-files to check for inconsistencies.

\n\n

adding your repository to github

\n\n

Chances are if you're versioning any kind of application with git, you'll want to add it to github at some point or another. Which is really great -- it allows other codeheads to fork and use your work, and ensures that even if your belligerent girlfriend hurls your laptop out the window (this not in reference to anybody at all) the app that you've devoted the last eight months of your life to will still be safe and sound.

\n\n

The first thing you'll want to do is register for an account at github if you already have one. You can do that here. The Open Source plan is free and provides 300mb of space for unlimited public repositories. If need to keep your files private for whatever reason, the micro account costs only $7/month and provides 5 private repositories. This is what I currently use, and is more than enough for my immediate needs.

\n\n

SSH with RSA

\n\n

Once you've got that setup, you'll want to create an RSA key in your ~/.ssh directory, and then add that same key to the SSH Public Keys section in your github Account Overview. This allows you to securely push and pull files from github without the use of any passwords or logins. Conveniently, github actually provides a pretty comprehensive tutorial on this whole process. Of course if you already have an RSA key in your ~/.ssh directory, you can just add that key to your github profile and don't need to generate a new one.

\n\n

creating the remote repository

\n\n

You've got a couple of options here. You can, of course, create the repository directly on the github website if you'd like, which most people seem to have no issue with. It might take 30 minutes to an hour before you can use the repository simply because of how the github system is setup.

\n\n

I personally have never had any success with creating repositories on the github site, and have gotten this error any time I've tried to push files to those repositories, even a few hours after creating them:

\n", nil, "
\n
Repository not found, if you've just created please try again in a few seconds.
\n
\n", nil, "

The only thing that's worked for me, and what I strongly recommend you do, is to just use the git remote command. It's certainly easy enough, and may potentially save you from the wild goosechase of troubleshooting that I had to endure.

\n\n

It's certainly easy enough. Again, just make sure you're in your application root directory, and call:

\n", nil, "
\n
user@domain$ cd my_app\nuser@domain$ git remote add origin git@github.com:YOUR_USERNAME/PROJECT_NAME.git
\n
\n", nil, "

You don't need to capitalize the YOUR_USERNAME and PROJECT_NAME bits, I only did that to ensure that you recognize and change them to those respective values.

\n\n

Once you've called that it's super simple to push all of the files of your current repository to github, like so:

\n", nil, "
\n
user@domain$ git push origin master
\n
\n", nil, "

And you'll see some output from git showing you what's moved where and why, and then --

\n\n

YOU'RE DONE. Your application is resting safely at github, and you can refresh the repository after every new commit using git push origin master.

\n\n

conclusion

\n\n

If you had experience with version control systems before, you now have experience with this one. If git is your first VCS, then congratulations and welcome to a heretofore undiscovered frontier of developmental productivity and organization.

\n\n

You're a git rockstar now. Just try to use it for good instead of evil.

\n"]

4 comments

Jeroen Bulters at 2009-08-11 12:20:58 UTC
["

I'm giving this post to my (less technical) co-workers... Making the change from Subversion to Git for all of our project in a few weeks. Nice post!

\n"]
Mike Zazaian at 2009-08-13 23:00:34 UTC
["

Awesome, Jeroen. I'm glad that it's useful to you.

\n"]
adrian at 2009-09-02 18:28:03 UTC
["

Thank you. This has been very helpful as I just pulled down git and I'm about to start using it this week.

\n"]
Mike Zazaian at 2009-09-02 22:03:48 UTC
["

No problem, Adrian -- I'm glad that you find this useful.

\n"]
login to post comments, or register to post a comment

latest links

Help.GitHub - Multiple SSH keys The article from github help mirroring this process
ones zeros majors and minors ones zeros majors and minors: esoteric adventures in solipsism, by chris wanstrath
ActiveScaffold A Ruby on Rails plugin for dynamic, AJAX CRUD interfaces

login

register activate reset

feeds

articles/rss

topics

staff

editor

about

doblock focuses on ruby, rails, and all things that can help ruby and/or rails programmers hone their skills.

Techniques, tutorials, news, and even free open-source applications, doblock seeks to fill in the cracks of the ruby/rails blogosphere.

doblock v. 0.10.1 powered by Rails