Apenas complementando sobre HEAD^ e HEAD~. É verdade que HEAD^^ é equivalente a HEAD~2, mas na verdade existe uma diferença mais fundamental sobre o funcionamento deles.
Para explicar a diferença, temos que lembrar que um commit pode ter mais de um pai, quando este é o resultado de um merge que não teve fast-forward.
O mais comum é quando eu faço git merge branch e não há fast-forward, pois aí o resultado é um commit com dois pais: o commit para onde o HEAD apontava e o commit para onde o branch aponta. Mas nada impede que eu faça algo como git merge branch1 branch2 branch3, e neste caso o commit resultante poderá ter até quatro pais (caso não seja possível fazer fast-forward em nenhum dos branches).
E é aí que usar ^ ou ~ começa a fazer diferença. Pois o ^N é usado para obter o enésimo pai, enquanto que ~N é usado para o enésimo ancestral.
Para entender melhor, segue um exemplo retirado da documentação oficial:
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
No caso, o commit A tem dois pais: B e C. O commit B tem 3 pais: D, E e F, e assim por diante.
Se eu fizer A^, A^1 ou A~1, o resultado é B. Agora, como eu chego em C a partir de A? Neste caso, eu uso A^2, ou seja, o "segundo pai de A".
Já se eu fizer A~2 ou A^^ (ou ainda A^1^1), eu chego em D. E para chegar em E, tenho que fazer algo como B^2 (o segundo pai de B), ou ainda A^^2 (pois A^ equivale a B, e depois com ^2 eu chego em E).
Essa é a diferença: A^2 é o segundo pai de A, enquanto A~2 é o ancestral de A "voltando duas gerações" (e considerando sempre o primeiro pai de cada geração).
Ainda usando o mesmo exemplo: para chegar em F, podemos fazer B^3 (o terceiro pai de B), ou A^^3 (o terceiro pai do primeiro pai de A). Para chegar em H, posso fazer algo como A~2^2 (pois com A~2 eu chego em D, e depois ^2 pega o segundo pai de D, que é H).
Enfim, esses atalhos existem porque fazem coisas diferentes: ^ olha apenas uma geração acima, e procura pelo enésimo pai (ou o primeiro, se nenhum número for especificado). Já o ~ vai subindo na "árvore genealógica", podendo olhar várias gerações anteriores.
O fato de A^^ ser equivalente a A~2 é mera consequência desta definição. Mas o intuito original não foi um ser atalho para o outro.