To the Future

Branches are great for trying new things, but you'll probably want some tools for moving your changes between them.

Simple scenario:

Well, first off, you'll want to checkout master because that is the branch you want to change, not crazyidea:

And second, you'll want to, uh, somehow.. add those changes to master.

There are two very different ways to do this: they are called "merge" and "rebase".

It is very important to understand the difference between merge and rebase and use the appropriate tool.

Fortunately, this is a very special case called a "fast-forward", and they behave exactly the same. Because crazyidea is in the future (or, more precisely, master is an ancestor of crazyidea), all Git has to do is move master forward to where crazyidea is.

In this case you can do either

git merge crazyidea
git rebase crazyidea

Both will fast-forward master to crazyidea.

Now then, here's a less simple scenario:

This is a hard problem to solve.

Git cannot simply move crazyidea to master, as you would lose the work you've done on crazyidea.

Remember, if you screw this up, you can always find your old commits using "git reflog" (or at least, you can do that until 30 days after they disappear).

So, first off, here is how rebase would approach the problem:

You can do this by checking out the crazyidea branch and doing

$ git rebase master

Git will "attempt" to replay what you did, but there's no guarantee that it will actually work, as sometimes patches don't apply.

It probably won't work if you modified the same lines of the same file in each branch.

If it can't apply a patch, Git will stop the process and ask you to resolve the conflict.

Remember, when you do a rebase that isn't a fast-forward, you're creating an alternate version of history. In this alternate history, you built your current branch (crazyidea) on top of everything that's in the other branch (master).

Git merge does this instead (actually, it can use many different strategies, but this is the common one):

You can do this by checking out the crazyidea branch and doing

$ git merge master

Like rebase, merge may have to stop and ask you to resolve a conflict.

Unlike rebase, merge does not create an alternate version of history. Instead, it "joins" the two branches into a new commit that shares both histories.

In this sense, a merge is kind of like the opposite of a branch.

You might think of a branch as allowing you to create an alternate universe. In one universe, you spent the day building a swingset. In the other, you repaired the roof. At the end of the day, you can merge the two universes back into one universe in which you have a swingset and a roof that does not leak.

However, the merge only changes the branch you had checked out. The master branch will not have your changes from the crazyidea branch. Just remember, Git will only alter a branch if you have it checked out.

Vincent Povirk