Viewing Git Commit History
Viewing Git commit history helps you understand code changes and development progress.
Git provides multiple commands and options to view commit history, from simple logs to detailed diffs.
Git commit history generally uses two common commands:
- git log- View the historical commit records.
- git blame <file>- View the historical modification records of the specified file in list form.
git log
After making a number of commits in Git, or after cloning a project, if you want to review the commit history, we can usegit logView with the command.
git logThe command is used to view the commit history in the Git repository.
git logIt displays all commit information from the latest to the earliest commit, including the commit hash, author, commit date, and commit message, etc.
git logThe basic syntax of the command is:
git log [选项] [分支名/提交哈希]
Common options include:
-p: Display the patch of the commit (specific changes).--oneline: Display commit information in a concise one-line format.--graph: Display branch and merge history in a graphical way.--decorate: Display the commits pointed to by branches and tags.--author=<作者>: Only show commits by a specific author.--since=<时间>: Only show commits after a specified time.--until=<时间>: Only show commits before a specified time.--grep=<模式>: Only show commit messages containing the specified pattern.--no-merges: Do not show merge commits.--stat: Display brief statistics, including modified files and line counts.--abbrev-commit: Use short commit hash values.--pretty=<格式>: Use a custom format to display commit information.
For the operations in our previous chapter, usegit logthe command to list the historical commit records as follows:
$ git log
commit d5e9fc2c811e0ca2b2d28506ef7dc14171a207d9 (HEAD -> master)
Merge: c68142b 7774248
Author: example <test@example.com>
Date: Fri May 3 15:55:58 2019 +0800
Merge branch 'change_site'
commit c68142b562c260c3071754623b08e2657b4c6d5b
Author: example <test@example.com>
Date: Fri May 3 15:52:12 2019 +0800
修改代码
commit 777424832e714cf65d3be79b50a4717aea51ab69 (change_site)
Author: example <test@example.com>
Date: Fri May 3 15:49:26 2019 +0800
changed the example.php
commit c1501a244676ff55e7cccac1ecac0e18cbf6cb00
Author: example <test@example.com>
Date: Fri May 3 15:35:32 2019 +0800
We can use the --oneline option to view a concise version of the history.
$ git log --oneline $ git log --oneline d5e9fc2 (HEAD -> master) Merge branch 'change_site' c68142b 修改代码 7774248 (change_site) changed the example.php c1501a2 removed test.txt、add example.php 3e92c19 add test.txt 3b58100 第一次版本提交
What this tells us is the development history of this project.
We can also use the --graph option to see when branches and merges appeared in the history. The following is the same command with the topology graph option enabled:
* d5e9fc2 (HEAD -> master) Merge branch 'change_site' |\ | * 7774248 (change_site) changed the example.php * | c68142b 修改代码 |/ * c1501a2 removed test.txt、add example.php * 3e92c19 add test.txt * 3b58100 第一次版本提交
Now we can see more clearly when work diverged and when it merged again.
You can also use--reverseparameter to display all logs in reverse order.
$ git log --reverse --oneline 3b58100 第一次版本提交 3e92c19 add test.txt c1501a2 removed test.txt、add example.php 7774248 (change_site) changed the example.php c68142b 修改代码 d5e9fc2 (HEAD -> master) Merge branch 'change_site'
If you only want to find the commit log of a specific user, you can use the command: git log --author. For example, say we want to find the part committed by Linus in the Git source code:
$ git log --author=Linus --oneline -5 81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory 3bb7256 make "index-pack" a built-in 377d027 make "git pack-redundant" a built-in b532581 make "git unpack-file" a built-in 112dd51 make "mktag" a built-in
If you need to specify a date, you can use several options: --since and --before, but you can also use --until and --after.
For example, if I want to see all commits in the Git project from three weeks ago and after April 18, I can run this (I also used the --no-merges option to hide merge commits):
$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges
5469e2d Git 1.7.1-rc2
d43427d Documentation/remote-helpers: Fix typos and improve language
272a36b Fixup: Second argument may be any arbitrary string
b6c8d2d Documentation/remote-helpers: Add invocation section
5ce4f4e Documentation/urls: Rewrite to accomodate transport::address
00b84e9 Documentation/remote-helpers: Rewrite description
03aa87e Documentation: Describe other situations where -z affects git diff
77bc694 rebase-interactive: silence warning when no commits rewritten
636db2c t3301: add tests to use --format="%N"
Common Options
Limit the number of commits displayed:
git log -n <number>
For example, show the last 5 commits:
git log -n 5
Show commits after the specified date:
git log --since="2024-01-01"
Show commits before the specified date:
git log --until="2024-07-01"
Only show commits by a specific author:
git log --author="Author Name"
Moregit logCommand can viewhttp://git-scm.com/docs/git-logOr usegit log --helpCommand to view help information.
git blame
git blameThe command is used to display, line by line, who introduced or modified each line of code in the specified file and when.
git blameIt can track the change history of each line in the file, including information such as author, commit hash, commit date, and commit message.
If you want to view the modification history of a specified file, you can use the git blame command, with the format as follows:
git blame [选项] <文件路径>
Common options include:
-L <起始行号>,<结束行号>: Only show code annotations within the specified line range.-C: For renamed or copied code lines, also trace the origin of the code line.-M: For moved code lines, also trace the origin of the code line.-C -Cor-M -M: For code lines with significant changes, perform further tracing.--show-stats: Display line count statistics for each author.
: Show code annotations and related information for each line of a file:
git blame <文件路径>
Only show code annotations within the specified line range:
git blame -L <起始行号>,<结束行号> <文件路径>
Trace the origin of renamed or copied code lines:
git blame -C <文件路径>
: Trace the origin of moved code lines:
git blame -M <文件路径>
: Show line count statistics:
git blame --show-stats <文件路径>
The git blame command displays modification records in a list, as in the following example:
$ git blame README ^d2097aa (tianqixin 2020-08-25 14:59:25 +0800 1) # Example Git 测试 db9315b0 (example 2020-08-25 16:00:23 +0800 2) # Example
For more content, you can usegit blame --helpView the full help documentation to learn more options and usage.
Recovery and rollback
Git provides multiple ways to restore and roll back to previous versions; different commands are suitable for different scenarios and needs.
Here are several common methods:
git checkout: Switch branches or restore files to a specified commit.git reset: Reset the current branch to the specified commit (soft reset, mixed reset, hard reset).git revert: Create a new commit to undo the specified commit without changing the commit history.git reflog: View historical operation records and recover lost commits.
1. git checkout: Check out a specific version of a file
The git checkout command is used to switch branches or restore files in the working directory to a specified commit.
Restore files in the working directory to a specific commit:
git checkout <commit> -- <filename>
For example, restore file.txt to the version at commit abc123:
git checkout abc123 -- file.txt
Switch to a specific commit:
git checkout <commit>
For example:
git checkout abc123
When switching to a specific commit in this way, you are in a detached HEAD state.
2. git reset: Reset the current branch to a specific commit
The git reset command can change the commit history of the current branch. It has three main modes: --soft, --mixed, and --hard.
--soft: Only reset HEAD to the specified commit, leaving the staging area and working directory unchanged.
git reset --soft <commit>
--mixed (default): Reset HEAD to the specified commit, reset the staging area, but keep the working directory unchanged.
git reset --mixed <commit>
--hard: Reset HEAD to the specified commit, resetting both the staging area and working directory.
git reset --hard <commit>
For example, reset the current branch to commit abc123:
git reset --hard abc123
3. git revert: Undo a commit
The git revert command creates a new commit to undo the specified commit. It does not change the commit history and is suitable for commits that have already been pushed to a remote repository.
git revert <commit>
For example, revert commit abc123:
git revert abc123
4. git reflog: View historical operation records
The git reflog command records all HEAD movements. Even if commits are deleted or reset, they can be recovered through reflog.
git reflog
You can use reflog to find a previous commit hash and restore to a specific state. For example:
git reset --hard HEAD@{3}
Example
The following is a comprehensive example demonstrating how to use these commands to recover historical versions:
View commit history:
git log --oneline
Assume the output is as follows:
abc1234 Commit 1 def5678 Commit 2 ghi9012 Commit 3
Switch to Commit 2 (in detached HEAD state):
git checkout def5678
Reset to Commit 2, keeping changes in the staging area:
git reset --soft def5678
Reset to Commit 2, unstaging the changes:
git reset --mixed def5678
Reset to Commit 2, discarding all changes:
git reset --hard def5678
Undo Commit 2:
git revert def5678
View reflog to recover lost commits:
git reflog
Find the previous commit hash and restore:
git reset --hard HEAD@{3}other extensions