Fscking Up With Git and How to Solve It

| Comments

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)

1
git tag boldly_go_tag

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

1
git reset --soft HEAD

create a branch out of your tagged commit, which is not on any branch just now

1
git checkout -b  boldly_go boldly_go_tag

Better:

1
git checkout -b boldly_go

to create the branch

1
2
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:

1
git commit --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:

1
git reset --hard HEAD^

if you want your commit to go away, but your code to still be around:

1
git reset --soft 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:

1
2
3
4
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 !!

1
2
3
4
$> 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.

1
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:

1
2
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

1
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 :)

Comments