Jabberwocky

Fscking up with git and how to solve it

Posted in Uncategorized by elisehuard on March 24, 2010

I’ve been using git for nearly two years now, but this job is the first time I’m using it with more than 2 people on the same project. And it’s different, I can tell you.

In this case you need a workflow: we adopted this one, also described here.
It’s a good workflow. But human error means that you can go wrong.

Forgetting to branch

The workflow demands that you do all your work on branches – that way you avoid merges on master, and can maintain a nice straight and clear master branch.
But, as you start working on a new feature, you might forget to do that

git checkout -b boldly_go

And start coding and committing on your local master.
What now ? Well, git offers an easy solution. Tag your latest commit (give it a label)

git tag boldly_go_tag

reset the master to its remote position (do not use –hard or you will lose your work)

git reset --soft HEAD

create a branch out of your tagged commit, which is not on any branch just now
git checkout -b boldly_go boldly_go_tag
Better:

git checkout -b boldly_go

to create the branch

git checkout master
git reset --hard origin/master

to reset the master to its original position.

My last commit message lacks poetry

Or I forgot to add this one file. Solution:
git commit -a --amend

Forget I ever did that last commit

Careful, this will remove any changes you added in that commit. This will only work locally, of course:
git reset --hard HEAD^

Going off the map

As you work on your branch, you want to do regular rebase with the remote master, to minimize any later merges and avoid surprises. After every commit:
git checkout master
git pull
git checkout boldly_go
git rebase master

Here’s where you can go very, very wrong: as long as you’re in rebase state, you’re in a situation where you’re NOT on a branch. So if after a coffee break you forgot you’re in rebase, and you continue working, you’re working into the void !!
$> git branch
*(no branch)
boldly_go
master

If you then try to do a rebase again to get up to date with master, you won’t find your commits where you expected them. Oh noes ! Where did my work go !
No panic (to be honest, i did panic a little): git keeps all your commits. You can find them in the .git/objects directory, if you care to have a look. What you just did is create a ‘dangling commit’, that is a commit unlinked to any branch. Fortunately, there’s the aptly named git fsck command.
git fsck | grep commit
(the grep commit helps separating the commits from the other dangling stuff) then use the SHA associated with your commit to create a tag:
git tag sos 9a4e6286aa2e2bd97334ad35b555169c2d3033b4
git checkout -b not_so_bold_now sos

this creates a branch based on the tag, and you can continue working.

another good one to know in that case is
git reflog
this shows all commits, dangling ones included, with their message, making it easier to find the commit you’re looking for. Same procedure for the rest.

This and many other tips, and sources, can be found on git-ready.
Thanks to Alain Ravet for some of the tips 🙂

Advertisements

2 Responses

Subscribe to comments with RSS.

  1. links for 2010-03-25 « Boskabout said, on March 25, 2010 at 6:04 pm

    […] Fscking up with git and how to solve it « Jabberwocky I’ve been using git for nearly two years now, but this job is the first time I’m using it with more than 2 people on the same project. And it’s different, I can tell you. (tags: git) […]

  2. […] Fscking up with git and how to solve it « Jabberwocky Niiice. (tags: git help fsck) Share with Shareomatic! […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: