http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde
Carats and tildes are relative commit markers in Git. They both mean "parent" but in a different way.
Most commonly used, they are the same. HEAD^1 (or HEAD^ for short) is the same as HEAD1 (HEAD). Always.
The difference comes when they stack. So HEAD^2 means "The second parent of HEAD". This only means anything if there's been a merge. In a merge, the main branch is parent #1; the merged in branch is parent 2. So, HEAD^2 will be the merged parent, whereas HEAD^1 will be the parent merged into.
Now, HEAD^^ is not the same as HEAD^2. HEAD^^ means the first parent of the first parent. This is just shorthand for HEAD^1^1. Evaluate from left to right.
But HEAD^^ is ugly. Isn't there something nicer. Yes. Tilde. Tilde ALWAYS means first parent. so HEAD~2 == HEAD^^.
Finally, you can stack tildes and carats. Say you wanted the merged in branch of two heads ago. That would be HEAD~2^2. I'm sure you will be doing that a lot. Not really.
That's from a good piece on carats and tildes