Wallis' Blog

My Journey from Wall Street To & Through Flatiron School

Learning Git the (Almost Kind of) Fun Way

I started learning to use Git about a week after I purchased my first-ever Mac. I was a true novice. Git seemed like a blizzard of words disconnected from their traditional definitions – merge / commit / rebase / push / pull all took on new meanings but I didn’t feel confident in my grasp of the subtleties that seemed to make the difference between an error message (or worse, messing up work flow) and a successful result.

Then my Flatiron School classmate (and fellow Wellesley alum!) Jane Vora posted an awesome graphics-based intro to GitHub that made Git start coming together in a much clearer way for me:

http://pcottle.github.com/learnGitBranching/

I love the graphic representations of what happens when you type in different commands. It’s like a (really nerdy) virtual race car driving game - exciting & fun, but even if you totally crash and burn, no one (or their code) actually gets hurt.

Get yourself into a pickle? (Or more accurately, a spaghetti-bowl-like mess of bungled commits, rebases, etc.?) No problem, just type reset and give it another go.

Some of my early points of confusion with Git were (answers below):

  1. What pushes you forward one step vs. staying in place?
  2. When you’re on a particular branch and invoke a command, are you doing that action to the branch you’re on or the branch you’re invoking?
  3. What’s the difference between rebase & merge?

On #1, I thought the following 3 pictures were really helpful.

A project with one commit starts out looking like this:
starting point

Then, if a commit takes place, that moves the version forward one step:
after commit

Or, if instead you make a branch, you make a copy without moving forward one step:
after branch

Part #3 of the Introduction Sequence, “Branches and Merging”, helped me understand that
you merge a named branch INTO the branch you are on

Let’s take a look at the solution for this exercise, “Merging in Git”

$ git checkout -b bugFix    //creates a branch and names it bugFix
$ git commit    
$ git checkout master    //switches you over to master
$ git commit    
$ git merge bugFix      //merges bugFix into master (you were on master)

After you complete the second-to-last step, “git commit”, it looks like this – notice you are on master, as denoted by *
before merge

When you “git merge bugFix”, it merges bugFix into master (the branch you were on), and looks like this:
completed merge

Lastly, I thought the rebase exercise in part 1 of “Master the Rebase Luke” was helpful in understanding rebase. The problem starts out like this:
rebase exercise starting point

and your goal is to recreate a single, chronological work history that looks like this:
rebase exercise goal

My first solution worked, but was 7 more steps than the suggested 7 steps. I realized I was being redudant by rebasing both branches onto each other:

$ git checkout another
$ git rebase side
$ git checkout side    
$ git rebase another
$ git checkout bugFix    
$ git rebase master    
$ git checkout master    
$ git rebase bugFix
$ git checkout another
$ git rebase master
$ git checkout side
$ git rebase bugFix
$ git checkout master
$ git rebase another

I learned that when you have a command that looks like this…

git rebase [branch_name]
(where [branch_name] is a placeholder for any branch name)

Git will rebase the branch you’re on ONTO the branch [branch_name]

So I eliminated the redundancy and came up with a solution in 8 steps, still 1 step shy of the goal:

$ git checkout bugFix
$ git rebase master
$ git checkout side
$ git rebase bugFix
$ git checkout another  
$ git rebase side
$ git checkout master   
$ git rebase another

A few minutes of searching turned up this helpful page which taught me that you can name two branches in your rebase commands. The link above uses more professional-looking notation, but the format of naming two branches in your rebase command works like this:

git rebase [branch_you_are_on] [branch_you_want_to_rebase_onto]

So I was able to combine my last two steps into one:

$ git checkout bugFix
$ git rebase master
$ git checkout side
$ git rebase bugFix
$ git checkout another  
$ git rebase side
$ git rebase another master  // rebases another onto master

Summary Conclusion

Question 1: What pushes you forward one step vs. staying in place?
Answer: Commit pushes you one step further. Merge leaves you in the same place, and creates a copy that has all the work of the commit you branched from.

Question 2: When you’re on a particular branch and invoke a command, are you doing that action to the branch you’re on or the branch you’re invoking?
Answer:
When you merge, you merge the named branch INTO the branch you’re on.
When you rebase and name one branch, you rebase the branch you’re on ONTO the named branch.
When you rebase and name two branches, you rebase the 1st branch (the branch you’re on) ONTO the 2nd branch.

Question 3: So what’s the difference between rebase & merge?
Answer: So this is one where I’m sure my understanding (and particularly when to invoke one vs. the other) will evolve, but I generally think of it as reconstructing a timeline and overlaying my changes (rebase) vs. mashing two branches together (merge).