GIT - HowTo's about "commits"

How to change the date of a commit ?

We'll start with the usual Git warning :
You may not alter history, except if it's known by you only.

If the commit to alter is the latest commit :

newDate='Fri Mar 13 09:24:32 2020 +0100'; GIT_COMMITTER_DATE="$newDate" git commit --amend --no-edit --date "$newDate"

Otherwise : not the latest commit / need to alter several commits / both :

The whole operation relies on an interactive git rebase, as already used to :

In the example below, let's say we want to alter the 2 latest commits.

  1. let's see these commits :
    git log
    commit e6fcd18d063a6624b5fdefd27c6df646280c2788
    Author: Thomas ANDERSON <thomas.anderson@metacortex.com>
    Date:   Fri Mar 13 14:57:12 2020 +0100		we're going to change this ...
    
    	a very interesting commit message
    
    commit 4e9c917085e0de16db01ae1b5d793e1a9013d3f3
    Author: Thomas ANDERSON <thomas.anderson@metacortex.com>
    Date:   Fri Mar 13 11:24:32 2020 +0100		... and this
    
    	another great commit message
  2. select the commits to alter :
    git rebase -i HEAD~2
    This opens the git-rebase-todo in my text editor :
    pick 4e9c917 another great commit message
    pick e6fcd18 a very interesting commit message
  3. declare both commits to be edited by changing pick into e (edit). Save and close.
  4. Back to the shell, you get :
    Stopped at 4e9c917...  another great commit message
    You can amend the commit now, with
    
    	git commit --amend
    
    Once you are satisfied with your changes, run
    
    	git rebase --continue
  5. you can now build the new date —at the appropriate format— with :
    Fri Mar 13 16:51:45 2020 +0100
  6. then apply it :
    newDate='Fri Mar 13 16:51:45 2020 +0100'; GIT_COMMITTER_DATE="$newDate" git commit --amend --no-edit --date "$newDate"; git rebase --continue
    [detached HEAD 4d24a66] another great commit message		done editing the 1st commit
     Date: Fri Mar 13 16:51:45 2020 +0100
     
    Stopped at e6fcd18...  a very interesting commit message	starting to edit the 2nd commit
    You can amend the commit now, with
    
    	git commit --amend
    
    Once you are satisfied with your changes, run
    
    	git rebase --continue
  7. build a new (posterior !) date for the 2nd commit, and repeat :
    newDate='Fri Mar 13 16:54:45 2020 +0100'; GIT_COMMITTER_DATE="$newDate" git commit --amend --no-edit --date "$newDate"; git rebase --continue
    [detached HEAD 75e964f] a very interesting commit message
     Date: Fri Mar 13 16:54:45 2020 +0100
     3 files changed, 39 insertions(+)
    Successfully rebased and updated refs/heads/master.
  8. git log
    commit 75e964f48eba2abee70a3530c9cd515fe2fbe155
    Author: Thomas ANDERSON <thomas.anderson@metacortex.com>
    Date:   Fri Mar 13 16:54:45 2020 +0100		as expected 
    
    	a very interesting commit message
    
    commit 4d24a66bf88b1c8504b31b540e51c97106851e9b
    Author: Thomas ANDERSON <thomas.anderson@metacortex.com>
    Date:   Fri Mar 13 16:51:45 2020 +0100		as expected 
    
    	another great commit message
  9. Enjoy !!!

How to split a commit ?

  1. make sure the environment is clean :
    • no uncommitted changes
    • the commit you're about to split belongs to you only (never rewrite public history, remember ?)
  2. find the commit you'd like to split and "how many commits back" it is :
    git log
    (let's consider it is 2 commits back)
  3. "rewind" to this commit :
    git rebase -i HEAD~2
    pick 17b92bc a great commit message		this is the commit I want to split
    pick d426342 one more wonderful piece of commit message
  4. state what you want to do with this commit by changing pick into edit :
    edit 17b92bc a great commit message
    pick d426342 one more wonderful piece of commit message
    Save and close your editor.
  5. Undo this commit :
    git reset HEAD^
    Unstaged changes after reset:
    M       roles/logrotate/defaults/main.yml
    M       roles/logrotate/tasks/main.yml
  6. Now, you just have to make 2 or more distinct commits normally
  7. Finish the interactive rebasing :
    git rebase --continue
    Successfully rebased and updated refs/heads/master.

How to refer to parent and ancestor commits ?

HEAD
reference to the latest commit of the current branch
commitId~n
reference to the nth ancestor of commitId (source):
  • commitId~1 : father of commitId
  • commitId~2 : grandfather of commitId
  • these are equivalent :
    • commitId~3
    • commitId^^^
    • commitId^1^1^1
commitId^n
reference to the nth parent of commitId. Parents are ancestors of the same level, since they are from the same "generation". (source):
  • commitId^1 : father of commitId
  • commitId^2 : mother of commitId
  • specials :
    • commitId^ is equivalent to commitId^1
    • commitId^0 is the commit itself
commitId_oldest..commitId_newest
range of commits between commitId_oldest and commitId_newest (source)

Example :

Parent commits are ordered left-to-right.
	G   H   I   J
	 \ /     \ /
	  D   E   F
	   \  |  / \
	    \ | /   |
	     \|/    |
	      B     C
	       \   /
	        \ /
	         A

	A =		= A^0
	B = A^		= A^1		= A~1
	C = A^2
	D = A^^		= A^1^1		= A~2
	E = B^2		= A^^2
	F = B^3		= A^^3
	G = A^^^	= A^1^1^1	= A~3
	H = D^2		= B^^2		= A^^^2		= A~2^2
	I = F^		= B^3^		= A^^3^
	J = F^2		= B^3^2		= A^^3^2

How to push only some local commits ?

Situation :

My status : git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
	(use "git push" to publish your local commits)
nothing to commit, working directory clean
My log : git log --oneline
2261c3a Revert blah blah blah ... This reverts commit 190898e77999bf4041fdc6d57ec18618743302e8
a102d0a FIX (ticket-104, part 2/2)		this commit
2fec5db FIX (ticket-104, part 1/2)		and this one too
ee00f4b Revert blah blah blah ... This reverts commit 7e16fa7173f10a662eecedbe166f42ffabacb41a
190898e ADD 'server_clone' for tests
7f2c929 FIX blah blah blah ...
8007cc6 CHANGE blah blah blah ...
3d835df FIX blah blah blah ...
5b047a8 FIX blah blah blah ...
082f84c CHANGE details
I'd like to push only the 2 marked commits to my origin server.

A wise (best practice !) solution would have been to create a dedicated branch to work on "ticket-104", but if I knew then, I wouldn't be on the verge of learning some git push hack .

Details :

Take me to the solution !

Detailed solution (source) :

  1. Let's setup a test environment :
    before=$PWD; tmpDir=$(mktemp -d --tmpdir=/run/shm playingWithGit.XXXXXXXX); repoName='myRepo'; repoDir="$tmpDir/$repoName.git"; workDir="$tmpDir/workDir"; mkdir -p "$repoDir" "$workDir"; cd "$repoDir"; git init --bare; cd "$workDir"; git clone "file://$repoDir/"; cd "$workDir/$repoName"; for i in {1..5}; do codeFile="file$i"; echo "this is some code : $i" > "$codeFile"; git add "$codeFile"; git commit -m "This is commit #$i ($codeFile)"; done; git log --oneline
    Initialized empty Git repository in /dev/shm/playingWithGit.0teQbNFk/myRepo.git/
    Cloning into 'myRepo'...
    warning: You appear to have cloned an empty repository.
    [master (root-commit) 0e0fe97] This is commit #1 (file1)
     1 file changed, 1 insertion(+)
     create mode 100644 file1
    [master 8488863] This is commit #2 (file2)
     1 file changed, 1 insertion(+)
     create mode 100644 file2
    [master af6011d] This is commit #3 (file3)
     1 file changed, 1 insertion(+)
     create mode 100644 file3
    [master 1503eac] This is commit #4 (file4)
     1 file changed, 1 insertion(+)
     create mode 100644 file4
    [master 828be7d] This is commit #5 (file5)
     1 file changed, 1 insertion(+)
     create mode 100644 file5
    828be7d (HEAD -> master) This is commit #5 (file5)
    1503eac This is commit #4 (file4)
    af6011d This is commit #3 (file3)
    8488863 This is commit #2 (file2)
    0e0fe97 This is commit #1 (file1)
  2. Let's push :
    git push origin master
  3. Now we have a local + a remote repository with some commits. Both are up-to-date :
    git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
  4. Now let's add some more commits :
    for i in {6..8}; do codeFile="file$i"; echo "this is some code : $i" > "$codeFile"; git add "$codeFile"; git commit -m "This is commit #$i ($codeFile)"; done; git log --oneline
    [master 725708b] This is commit #6 (file6)
     1 file changed, 1 insertion(+)
     create mode 100644 file6
    [master 0021c6d] This is commit #7 (file7)
     1 file changed, 1 insertion(+)
     create mode 100644 file7
    [master 58ce856] This is commit #8 (file8)
     1 file changed, 1 insertion(+)
     create mode 100644 file8
    58ce856 (HEAD -> master) This is commit #8 (file8)
    0021c6d This is commit #7 (file7)
    725708b This is commit #6 (file6)
    828be7d (origin/master) This is commit #5 (file5)
    1503eac This is commit #4 (file4)
    af6011d This is commit #3 (file3)
    8488863 This is commit #2 (file2)
    0e0fe97 This is commit #1 (file1)
  5. Now I'll try to push, providing the ID of "commit #7" :
    git push origin 0021c6d:master && git log --oneline
    58ce856 (HEAD -> master) This is commit #8 (file8)
    0021c6d (origin/master) This is commit #7 (file7)
    725708b This is commit #6 (file6)
    828be7d This is commit #5 (file5)
    1503eac This is commit #4 (file4)
    af6011d This is commit #3 (file3)
    8488863 This is commit #2 (file2)
    0e0fe97 This is commit #1 (file1)

    I've actually pushed the commits This is commit #6 (file6) and This is commit #7 (file7)

    git push remoteName commitId:remoteBranchName
    actually pushes the full history from the beginning of times until commitId included.

  6. Let's check this with more commits to push :
    for i in {9..13}; do codeFile="file$i"; echo "this is some code : $i" > "$codeFile"; git add "$codeFile"; git commit -m "This is commit #$i ($codeFile)"; done; git log --oneline
    07b6bb8 (HEAD -> master) This is commit #13 (file13)
    65100fc This is commit #12 (file12)
    48e1df2 This is commit #11 (file11)
    a51d31f This is commit #10 (file10)
    4abcf38 This is commit #9 (file9)
    58ce856 This is commit #8 (file8)
    0021c6d (origin/master) This is commit #7 (file7)
    725708b This is commit #6 (file6)
    828be7d This is commit #5 (file5)
    1503eac This is commit #4 (file4)
    af6011d This is commit #3 (file3)
    8488863 This is commit #2 (file2)
    0e0fe97 This is commit #1 (file1)
  7. Now we'll push commits 11 and 9, in this order (!!!). To do so, we'll have to stack them on top of the latest commit known by "origin" : #7
    git squash 7
    • In the command above, 7 is the number of commits we'll considering while squashing. This appears to be a 7 again, like the "head" of the remote branch, but this is purely coincidental.
    • The display below is the re-ordered list of commits during git rebase. It's in the opposite order of git log.
    pick 0021c6d This is commit #7 (file7)
    pick 48e1df2 This is commit #11 (file11)
    pick 4abcf38 This is commit #9 (file9)
    pick 58ce856 This is commit #8 (file8)
    pick a51d31f This is commit #10 (file10)
    pick 65100fc This is commit #12 (file12)
    pick 07b6bb8 This is commit #13 (file13)
  8. Checking the re-ordering :
    git log --oneline -8
    02c9072 (HEAD -> master) This is commit #13 (file13)
    8082015 This is commit #12 (file12)
    cf3cda0 This is commit #10 (file10)
    e794a70 This is commit #8 (file8)
    926ad50 This is commit #9 (file9)
    117bb7f This is commit #11 (file11)
    0021c6d (origin/master) This is commit #7 (file7)
    725708b This is commit #6 (file6)
  9. And also :
    git status
    On branch master
    Your branch is ahead of 'origin/master' by 6 commits.
    	(use "git push" to publish your local commits)
  10. Now, let's push the 2 commits sitting on top of "origin/master", by giving the commit ID of commit #9 :
    git push origin 926ad50:master
    Counting objects: 6, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (4/4), done.
    Writing objects: 100% (6/6), 579 bytes | 579.00 KiB/s, done.
    Total 6 (delta 2), reused 0 (delta 0)
    To file:///run/shm/playingWithGit.0teQbNFk/myRepo.git/
    	0021c6d..926ad50	926ad50 -> master
  11. Checking locally :
    git status
    On branch master
    Your branch is ahead of 'origin/master' by 4 commits.
    	(use "git push" to publish your local commits)
    And :
    git log --oneline
    02c9072 (HEAD -> master) This is commit #13 (file13)
    8082015 This is commit #12 (file12)
    cf3cda0 This is commit #10 (file10)
    e794a70 This is commit #8 (file8)
    926ad50 (origin/master) This is commit #9 (file9)
    117bb7f This is commit #11 (file11)
    0021c6d This is commit #7 (file7)
    725708b This is commit #6 (file6)
    828be7d This is commit #5 (file5)
    1503eac This is commit #4 (file4)
    af6011d This is commit #3 (file3)
    8488863 This is commit #2 (file2)
    0e0fe97 This is commit #1 (file1)
  12. Checking on the "origin" side :
    cd "$repoDir"; git log --oneline; cd "$workDir/$repoName"
    926ad50 (HEAD -> master) This is commit #9 (file9)
    117bb7f This is commit #11 (file11)
    0021c6d This is commit #7 (file7)
    725708b This is commit #6 (file6)
    828be7d This is commit #5 (file5)
    1503eac This is commit #4 (file4)
    af6011d This is commit #3 (file3)
    8488863 This is commit #2 (file2)
    0e0fe97 This is commit #1 (file1)
  13. Done playing, let's clean up :
    cd "$before"; [ -d "$tmpDir" ] && rm -rf "$tmpDir"

Solution :

  1. Find the remote (origin) HEAD. Several methods to do so :
    • git status may display things like : Your branch is ahead of 'origin/master' by n commits.
    • on the remote side : git log --oneline will display this (by default on recent Git versions)
  2. Re-order commits so that the commits to be pushed are sitting right on top of the latest commit known to the remote (i.e. "remote HEAD")
  3. Push the n local commits by giving the commit ID of the last commit (in current history order) to be pushed (source) :
    git push remoteName commitId:remoteBranchName
    Which gives :
    git push origin 720aebc:master

How to squash several commits into a single one ?

Usage :

NEVER EVER rebase commits which you have already pushed to a remote repository !

Example :

Preliminary :

testFile='./myFile'; testDir='./myDir'
mkdir "$testDir"; cd "$testDir"
git init; touch "$testFile"; git add "$testFile"; git co "$testFile" -m "Initial version (empty)"; git log
for i in {1..4}; do echo "This is edit number $i" >> "$testFile"; git co "$testFile" -m "Commit #$i"; done; git log

Merge 4th commit (latest) into 3rd :

git rebase -i HEAD~2 outputs :
pick 897931d Commit #3
pick 25d3585 Commit #4
Edit to squash the 4th commit into the 3rd (forget about commit messages for the moment) :
pick 897931d Commit #3
s 25d3585 Commit #4
Save and exit. Then you'll be prompted for the final commit message :
# This is a combination of 2 commits.
# The first commit message is:

Commit #3

# This is the 2nd commit message:

Commit #4
Enter your own commit message :
Squashed #4 into #3
Save and exit. Check the result with git log :
Squashed #4 into #3
Commit #2
Commit #1
Initial version (empty)

Squash commits 2, 3 and 4 into a single one :

Make sure you've run the cleaning then preliminary steps before going further.

git rebase -i HEAD~3 outputs :
pick 04f56e2 Commit #2
pick 0887de3 Commit #3
pick 5410e2c Commit #4
Edit to fixup the commits 2, 3 and 4 and use the message of the 2nd commit (this method won't prompt for a commit message):
pick 04f56e2 Commit #2
f 0887de3 Commit #3
f 5410e2c Commit #4
Save and exit. Check with git log :
Commit #2
Commit #1
Initial version (empty)
See changes made with this "new commit number 2" (that is also the latest so far) : git show HEAD~1..HEAD $testFile :
	Commit #2

diff --git a/myFile b/myFile
index 32671c8..4e96082 100644
--- a/myFile
+++ b/myFile
@@ -1 +1,4 @@
 This is edit number 1
+This is edit number 2
+This is edit number 3
+This is edit number 4

Merge commits 2 and 3 into a single one :

Make sure you've run the cleaning then preliminary steps before going further.

git log shows :
commit 402957e89a359ce2bd4c9c24cd658dbe25a4f155
	Commit #4

commit 331174ab513dda7861100997ae6e4dbf66d18eae
	Commit #3

commit de0db9b72fad2e52b23cbfdd51f8714561d9e0e6
	Commit #2

commit 8c93f6861a17388d691cfb5a985bbb9161c4a8f1
	Commit #1

commit 8ee9ad23f95c146d48c7c7a7f58d03a3140e5455
	Initial version (empty)
We're at Commit #4 (HEAD) and we want to make changes right after Commit #1, no matter where these changes stop. In other words, we want to start working from Commit #1 (excluded), which can be refereed to as HEAD~3 (details)
git rebase -i HEAD~3
pick de0db9b Commit #2
pick 331174a Commit #3
pick 402957e Commit #4

# These lines can be re-ordered; they are executed from top to bottom.
Edit (this is where the magic takes place Forget about commit message for the moment :
pick de0db9b Commit #2
s 331174a Commit #3
pick 402957e Commit #4
Save and exit. You'll be prompted for a new commit message :
# This is a combination of 2 commits.
# The first commit message is:

Commit #2

# This is the 2nd commit message:

Commit #3
Change this into :
Squashed #3 into #2
And check the result : git log :
commit ff477d71a329265bf2033d0d0ccd5a1c7e60c37c
	Commit #4

commit 394bc1c28075e6457a795bd69d58deda20f00a20
	Squashed #3 into #2

commit 8c93f6861a17388d691cfb5a985bbb9161c4a8f1
	Commit #1

commit 8ee9ad23f95c146d48c7c7a7f58d03a3140e5455
	Initial version (empty)
See changes made with this "new commit" : git show HEAD~2..HEAD~1 $testFile :
commit 394bc1c28075e6457a795bd69d58deda20f00a20
	Squashed #3 into #2

diff --git a/myFile b/myFile
index 32671c8..987d059 100644
--- a/myFile
+++ b/myFile
@@ -1 +1,3 @@
 This is edit number 1
+This is edit number 2
+This is edit number 3

Cleaning :

rm -rf .git; cd ..; [ -d "$testDir" ] && rm -r "$testDir"; unset testFile testDir

How to view details of past commits ?

General rule

the diff only
git diff olderCommit..newerCommit
the diff + commit ID + author + commit message

To highlight the changes made between commits, use --word-diff (works with diff / show / log) :

git diff olderCommit..newerCommit --word-diff

Changes made to myFile in the latest n commits

git show HEAD~n..HEAD myFile

How to correct mistakes in old commits ?

If you want to fix an error in the latest commit, git commit --amend should do the trick. Read more.
Otherwise, keep reading here

Only rewrite that part of history which you alone possess (source) : don’t amend any commit you have already pushed (source) !

Situation :

First things first, here's my history : git log
commit 7ef72d73aa0ee4c67007e66a3351ed1ee2df6998
Author: Thomas ANDERSON <thomas.anderson@metacortex.com>
Date:	Fri Apr 24 15:31:11 2015 +0200

	Cosmetics

commit 2b9bbbf3f7463e0c0526a69edec10a708dacada3
Author: root <root@localhost>				OOOPS !
Date:	Fri Apr 24 15:21:21 2015 +0200

	BUGFIX: make sure configuration files use the Unix line ending format, not DOS/Windows

commit f93811c3dcaabed86df54916ea84fbbfcf521435
Author: Thomas ANDERSON <thomas.anderson@metacortex.com>
Date:	Fri Apr 24 11:44:25 2015 +0200

The error we'll fix here is this commit made as root.

Solution :

  1. Put away pending changes (if any) : git stash
  2. Get the current branch name : git branch
    * master
  3. Checkout the bad commit : git checkout 2b9bbbf3f7463e0c0526a69edec10a708dacada3, which outputs :
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.
    
    ...
    
    HEAD is now at 2b9bbbf... BUGFIX: make sure configuration files use the Unix line ending format, not DOS/Windows
  4. Make the necessary changes :
    • In this example, since I just committed with the wrong user, there's nothing to do, the fix will be made at the next step.
    • If the change I'd like to commit (1 single change in 1 single file) is currently stashed, I have to extract it first (source) : git checkout stash@{0} -- path/to/file
      path/to/file is what is reported by git s.
  5. Commit changes :
    • In the specific case of this example (changing the author of a commit) : git commit --amend --reset-author
    • In the general case : git commit --amend
  6. Now let's rebase with : git rebase --onto HEAD badCommitId branchName
    git rebase --onto HEAD 2b9bbbf3f7463e0c0526a69edec10a708dacada3 master
    First, rewinding head to replay your work on top of it...
    Applying: Cosmetics
  7. Restore pending changes (if any) : git stash apply

How to list files modified by a commit ?

How to view git log of a renamed file ?

Situation :

git log myFile returns no error, but I can remember this file was initially named my file. I have renamed + committed it, but now, how can I view its history when it was still named my file ?

Details :

Solution :

git log -S my file

will show the history of my file starting at the rename commit, back to the beginning of times.

How to cancel a commit ?

Cancel the latest commit :

Available methods :
git revert commitId
create a new commit that "unchanges" what was changed by commit commitId (example). This can be used on any commit, not only the latest one.
git reset HEAD^
remove a commit from history and leave changes made by this commit as unstaged changes (example)
Examples :
git revert commitId :

tempDir=$(mktemp -d --tmpdir XXXXXXXX); commitMessage='This is commit '; cd "$tempDir"; git init; echo 'Hello World' > myFile; git add myFile; git co -m 'Initial version'; for i in {1..2}; do echo "This line will be committed by commit #$i" >> myFile; git add myFile; git co -m "$commitMessage#$i"; done; git log --oneline; idOfLatestCommit=$(git log --oneline | awk "/$commitMessage#$i/ {print \$1}"); echo -e "\nID of latest commit : '$idOfLatestCommit'\nREVERTING...\n"; git revert --no-edit "$idOfLatestCommit"; git log --oneline; echo; git s; echo; cat myFile; cd -; [ -d "$tempDir" ] && rm -rf "$tempDir"

Outputs :

aa94778 This is commit #2
5915e56 This is commit #1
9baee48 Initial version

ID of latest commit : 'aa94778'
REVERTING...

[master 5ba510a] Revert "This is commit #2"
 1 file changed, 1 deletion(-)
5ba510a Revert "This is commit #2"
aa94778 This is commit #2
5915e56 This is commit #1
9baee48 Initial version

On branch master
nothing to commit (use -u to show untracked files)	nothing unstaged

Hello World
This line will be committed by commit #1		changes are gone : working copy altered
git reset HEAD^ :

tempDir=$(mktemp -d --tmpdir XXXXXXXX); cd "$tempDir"; git init; echo 'Hello World' > myFile; git add myFile; git co -m 'Initial version'; for i in {1..2}; do echo "This line will be committed by commit #$i" >> myFile; git add myFile; git co -m "This is commit #$i"; done; git log --oneline; echo -e '\nRESETTING...\n'; git reset HEAD^; git log --oneline; git s; cat myFile; cd -; [ -d "$tempDir" ] && rm -rf "$tempDir"

Outputs :

4caee4f This is commit #2
b78d9b4 This is commit #1
e4dd720 Initial version

RESETTING...

Unstaged changes after reset:
M	myFile
b78d9b4 This is commit #1
e4dd720 Initial version
On branch master
Changes not staged for commit:
	(use "git add <file>..." to update what will be committed)
	(use "git checkout -- <file>..." to discard changes in working directory)

 modified:	myFile

no changes added to commit (use "git add" and/or "git commit -a")
Hello World
This line will be committed by commit #1
This line will be committed by commit #2	changes are still there : working copy unaltered
  • The commit This is commit #2 no longer exists
  • myFile is back to its state right before doing the This is commit #2 commit, i.e. with some unstaged changes. This is confirmed by git s as well as by the final cat.

Jump several commits back (source) :

  • HEAD^ : 1 commit back
  • HEAD^^ or HEAD~2 : 2 commits back
  • d6d98923868578a7f38dea79833b56d0326fcba1 : full commit ID
  • d6d9892 : short commit ID. Works as long as this doesn't collide with another commit ID