Review¶
log¶
Filter and sort¶
$ git log [-n COUNT]lists the commit history of the current branch.
-nlimits the number of commits to the specified number.
$ git log [--after="YYYY-MM-DD"] [--before="YYYY-MM-DD"]Commit history filtered by date.
Relative specifications such as
1 week agooryesterdayare also permitted.$ git log --author="VEIT"filters the commit history by author.
It is also possible to search for several authors at the same time, for example:
$ git log --author="VEIT|VSC"$ git log --grep="TERM" [-i]filters the commit history for regular expressions in the commit message.
-iignores upper and lower case.
$ git log -S"FOO" [-i]filters commits for specific lines in the source code.
-iignores upper and lower case.
$ git log -G"BA*"filters commits for regular expressions in the source code.
$ git log -- PATHfilters the commit history for specific files.
$ git log MAIN..FEATUREfilters for different commits in different branches, in our case between the
MAINandFEATUREbranches.However, this is not the same as
git log FEATURE..MAIN. Let’s take the following example:A - B main \ C - D feature
$ git log MAIN..FEATUREshows changes in
FEATUREthat are not contained inMAIN, that is, commitsCandD.$ git log FEATURE..MAINshows changes in
MAINthat are not contained inFEATURE, that is, commitB.$ git log MAIN...FEATUREshows the changes on both sides, that is, commits
B,CandD.
$ git log --follow PATH/TO/FILEThis ensures that the log shows changes to a single file, even if it has been renamed or moved.
You can activate
--followfor individual file calls by default by activating thelog.followoption in your global configuration:$ git config --global log.follow true
Then you no longer have to enter
--follow, but only the file name.$ git log -LWith the -L option, you can perform a refined search by checking the log of only part of a file:
$ git log -L LINE_START_INT|LINE_START_REGEX,LINE_END_INT|LINE_END_REGEX:PATH/TO/FILE$ git log -L :FUNCNAME_REGEX:PATH/TO/FILE
This function allows you to thoroughly search through the history of a single function, class or other code block. It is ideal for finding out when something was created and how it was changed so that you can correct, refactor or delete it with confidence.
For more comprehensive investigations, you can also track multiple blocks. You can use multiple
-Loptions at once.$ git log --reverseThe log usually displays the latest commit first. You can reverse this with
--reverse. This is particularly useful if you are analysing with the-Sand-Goptions already mentioned. By reversing the order of the commits, you can quickly find the first commit that added a specific string to the codebase.
View¶
$ git log --stat --patch|-p--statA summary of the number of changed lines per file is added to the usual metadata.
--patch|-padds the complete commit diff to the output.
$ git log --oneline --decorate --graph --all|FEATUREdisplay the history graph with references, one commit per line.
--onelineOne commit per line.
--decorateThe prefixes
refs/heads/,refs/tags/andrefs/remotes/are not output.--graphThe log usually smoothes historical branches and displays commits one after the other. This hides the parallel structure of the history when merging branches.
--graphdisplays the history of the branches in ASCII format.--all|FEATURE--allshows the log for all branches;FEATUREonly shows the commits of this branch.
reflog¶
With git reflog, your Git repository is not checked a second time. Instead, it displays the reference log, a record of all commits made. The reflog not only tracks changes to a branch, it also records changes to the current commit, branch changes, rebasing, etc. You can use it to find all unreachable commits, even those on deleted branches. This allows you to undo many otherwise destructive actions.
Let’s look at the basics of using reflog and some typical use cases.
Warning
The reflog is only part of your local repository. If you delete a repository and clone it again, the new clone will have a fresh, empty reflog.
Show the reflog for HEAD¶
$ git reflogIf no options are specified, the command displays the reflog for
HEADby default. It is short forgit reflog show HEAD. git reflog has other subcommands to manage the log, but show is the default command if no subcommand is passed.
1$ git reflog
212bc4d4 (HEAD -> main, my-feature-branch) HEAD@{0}: merge my-feature-branch: Fast-forward
3900844a HEAD@{1}: checkout: moving from my-feature-branch to main
412bc4d4 (HEAD -> main, my-feature-branch) HEAD@{2}: commit (amend): Add my feature and more
5982d93a HEAD@{3}: commit: Add my feature
6900844a HEAD@{4}: checkout: moving from main to my-feature-branch
7900844a HEAD@{5}: commit (initial): Initial commit
The output is quite dense.
Each line is a reflog entry, the most recent first.
The lines start with the abbreviated SHA of the corresponding commit, for example
12bc4d4.The first entry is what
HEADcurrently refers to:(HEAD -> main, my-feature).The names
HEAD@\{N}are alternative references for the specified commits.Nis the number of returning reflog entries.remaining text describes the change. Above you can see several types of entries:
commit: MESSAGEfor commitscommit (amend): MESSAGEfor a commit changecheckout: moving from SRC TO DSTfor a branch change
There are many other possible types of entries. The text should be descriptive enough that you can understand the process without looking it up in the documentation. In most cases, you will want to look through such reflog entries to find the corresponding commit SHA.
Show the reflog for a branch¶
You can focus on entries for a single branch by using the explicit subcommand
show and the branch name:
$ git reflog show my-feature-branch
12bc4d4 (HEAD -> main, my-feature-branch) my-feature-branch@{0}: commit (amend): Add my feature and more
982d93a my-feature-branch@{1}: commit: Add my feature
900844a my-feature-branch@{2}: branch: Created from HEAD
Show timestamps of the entries¶
If you need to distinguish between similarly titled changes, the timestamps can
help. For relative timestamps you can use --date=relative:
$ git reflog --date=relative
12bc4d4 (HEAD -> main, my-feature) HEAD@{37 minutes ago}: merge my-feature-branch: Fast-forward
900844a HEAD@{37 minutes ago}: checkout: moving from my-feature-branch to main
12bc4d4 (HEAD -> main, my-feature-branch) HEAD@{37 minutes ago}: commit (amend): Add my feature and more
982d93a HEAD@{38 minutes ago}: commit: Add my feature
900844a HEAD@{39 minutes ago}: checkout: moving from main to my-feature-branch
900844a HEAD@{40 minutes ago}: commit (initial): Initial commit
And for absolute timestamps you can also use --date=iso:
$ git reflog --date=iso
12bc4d4 (HEAD -> main, my-feature) HEAD@{2024-01-11 15:26:53 +0100}: merge my-feature-branch: Fast-forward
900844a HEAD@{2024-01-11 15:26:47 +0100}: checkout: moving from my-feature-branch to main
12bc4d4 (HEAD -> main, my-feature-branch) HEAD@{2024-01-11 15:26:11 +0100}: commit (amend): Add my feature and more
982d93a HEAD@{2024-01-11 15:25:38 +0100}: commit: Add my feature
900844a HEAD@{2024-01-11 15:24:37 +0100}: checkout: moving from main to my-feature-branch
900844a HEAD@{2024-01-11 15:23:56 +0100}: commit (initial): Initial commit
Passes all options that git log supports¶
git reflog show has the same options as git log. For example, you can
use --grep to search for commit messages that mention my feature
without case-sensitivity:
$ git reflog -i --grep 'my feature'
12bc4d4 (HEAD -> main, my-feature-branch) HEAD@{0}: merge my-feature: Fast-forward
12bc4d4 (HEAD -> main, my-feature-branch) HEAD@{2}: commit (amend): Add my feature and more
982d93a HEAD@{3}: commit: Add my feature
Note the expiry of entries¶
Reflog entries expire after a certain time when Git runs the automatic gc process for your repository. This expiration time is
controlled by two gc.* options:
gc.reflogExpireThe general expiration time, which is set to 90 days by default.
gc.reflogExpireUnreachableThe expiry time for entries relating to commits that can no longer be reached is set to 30 days by default.
You can increase these options to a longer time frame, but this is rarely useful.
fsck¶
git fsck is the last resort when a commit
is no longer in the reflog (for example, if you have ‘lost’ it with git
stash drop). With git fsck, you can list all commit IDs that are not
referenced.