Thursday, February 12, 2009

Branching after committing locally in git

Today I found out that one of my co-workers had a local commit that he wanted to undo, so that he could work on another task that he actually wanted his earlier commit to come after. His question was: How do I undo a commit but keep the files? The answer to that is simple: simply use git reset HEAD^ to point master to the commit before the current HEAD. By default, this leaves the checked out code alone, and it remains as uncommitted changes locally. git reset --hard will check out the previous changes and blow your commit away completely.

On the other hand, branches in git are essentially just pointers to nodes in the repository tree. So, consider doing this instead:

  1. git checkout master
  2. git branch new_branch
  3. git reset --hard HEAD^
What does this do? It creates a new branch that points to the HEAD of the current master, then resets master to point to the previous commit from HEAD. Once that's done, you can continue working in the branch, or make further commits to HEAD. Then, when you're ready to continue work in new_branch, you can rebase it against master and continue on your way as usual!

2 comments:

  1. this is funny. i was just at a ruby meetup in san francisco the other night, and this german guy named wolfram was giving a talk on git.

    then josh susser talked about procs and lambdas, and all the insane ambiguity of:
    proc
    Proc.new
    lambda {}
    ->() {}
    f[]
    f.()
    f.call()
    etc.

    I find myself wishing there were no blocks, just lambdas, treated the same way JavaScript treats functions...

    okay, this is off topic. :)

    ReplyDelete
  2. Hey Alf. Another way of doing this: git checkout -b new_branch master^

    You'd do the new work on new_branch, unlike in the reset example, but all branches are the same in git anyway.

    ReplyDelete