Saturday, May 11, 2013

Git 101


A couple sections of the internet that I've been on have been like "What's Git, and why should I care?" This is a repost of my answer to that.

It doesn't really follow my preferred format for my blog, as it is a tutorial instead of a dialogue, but that's alright. My overall goal is the sharing of information, so share I shall.



Git is revision control. That means if you mess up, rather than having to remember what your old code looked like and did, you can just revert back to a previous state.

Here's something fairly important to note:

This is NOT Revision Control. This is a disaster. I know this because I did it this way, once upon a time.


Git allows for remote hosting on sites like Bitbucket, Github, and even Google Code. That way, you can pull your code down from a remote location on computers, edit it, and push it back up. It's essentially a cloud of data storage, like Dropbox, but smarter for code.

This IS Revision Control. It is noticeably easier to navigate, and in general, use.


~~THE BASICS~~
If in Windows: Download Git Bash, because I like me a command prompt, and it teaches you what's going on a bit better.
If in Linux or OS X: There are handy-dandy installers for integrating Git commands, such as "sudo apt-get install git" if I recall correctly.
Cool, we now have a Command Prompt for Git. It uses Unix-based commands, like "ls" and "cd" and "mkdir" and the like, so you'll notice the Windows Git Bash shell is really a cygwin shell. Not a coincidence.
~~LINK TO REMOTE REPOSITORIES~~
So now, let's assume you have some code that you want to start a revision control system on.
We'll call it hello_world.cpp, in a folder called SENIOR_DESIGN_PROJECT.
On your remote hosting site (Bitbucket has unlimited free repositories, or folders-of-code, and Github has something similar for students IIRC), you can click the big MAKE NEW REPOSITORY button, and it will create a new empty remote repository.
THEN.
You can run a command (in your respective Terminal, be it Terminal in Linux/OSX, or Git Bash in Windows) on your code folder, as prompted by the $ symbol:
 $ git init
to initialize that folder to be compatible with Git. You'll have to do this once per project.
Next up, link that folder to your remote repository by telling it where EXACTLY to push things back up to the cloud (as discussed earlier).
 $ git remote add origin http://some.github.repository/SENIOR_DESIGN_PROJ.git
What this says is "this local codebase is linked to a remote codebase, which we'll call 'origin', found on this git repository at this address."
Follow it up with:
$ git add .
$ git commit -m "Initial Commit."
$ git push -u origin master
to say "push anything, and all future things, to the Master branch". For simplicity's sake, we'll only care about the Master branch.
~~WHAT DID I JUST DO~~
Let's run through the commands you just used one by one real quick.
 $ git add .
Adds all NEW/CHANGED files (i.e. hello_world.cpp in this case) to a pending STAGING area.
 $ git commit -m "message" 
Commits that staging area, locking it down as some kind of feature or bugfix or whatever MESSAGE is. This is known as a "commit".
 $ git push
Actually pushes this code up to your remote repo. Notice I purposely left out all the extra flags -- you only really need those for your FIRST ever push for this project!
You can see what files have been last changed between commits with
 $ git status
And pull down changes from other users/computers with
 $ git pull
Now let's consider a different computer.
On a different computer (we'll call it C2), if you run:
 $ git clone http://some.github.repository/SENIOR_DESIGN_PROJ.git
You'll be prompted for your password, then your computer will go off and grab the most recent code and store it in a folder called SENIOR_DESIGN_PROJ.
You make some changes to the source code. Fix a bug, whatever.
SO:
 $ git add .
 $ git commit -m "I fixed that stupid memory leak."
 $ git push
And back on C1:
 $ git pull
Congrats, you just pulled back down the bugfix that you wrote on a entirely different computer! This is how teams are able to work on a codebase simultaneously -- they all commit and merge it all into branches. In our case, we, again, only care about the Master branch.
~~I DONE GOOFED~~
Or, you make some changes, decide these were bad changes, and you want to roll back:
 $ git checkout <filename>
resets a single file by removing it from the Staging area.
 $ git reset HEAD --hard
resets your entire codebase to the previous commit.
 $ git checkout commit-number
resets your entire codebase to an arbitrary commit-number (IIRC). This is VERY handy if you mess up your code base, but an earlier version worked.

TL;DR
Set up git repo on a project folder:
 $ git init
Set up a link to a remote repo:
 $ git remote add origin http://blahblahblah
Do an initial commit and push:
 $ git add .
 $ git commit -m "Initial commit"
 $ git push -u origin master
Make some changes, see what they were:
 $ git status
Pull to make sure you didn't have conflicting changes stashed in the remote repository (i.e. a team member fixed it while you were working on it, and you don't want to mess up their fix, you should just reset your own and use theirs)
 $ git pull
 $ git checkout hello_world_teammate_revised.cpp
Make some better changes, and push them back up:
 $ git add .
 $ git commit -m "I fixed teammates bug!"
 $ git push
That's basically the basics! With this you can store all your code remotely, navigate the remote location to find commit numbers, roll back code as need be (either single files, or ENTIRE groups of files to previously working commits), and work on a project with a team!

Next Week: (Introduction to) Introduction to Object Oriented Programming Week, Part 1: A Different Kind Of Lego

No comments:

Post a Comment