How to show first commit by 'git log'?
GitGit Problem Overview
I have a project which has long history. I want to show the first commit on git.
How do I do this?
Git Solutions
Solution 1 - Git
I found that:
git log --reverse
shows commits from start.
Solution 2 - Git
Short answer
git rev-list --max-parents=0 HEAD
(from [tiho's comment][1]. As [Chris Johnsen notices][2], --max-parents
was introduced after this answer was posted.)
Explanation
Technically, there may be more than one root commit. This happens when multiple previously independent histories are merged together. It is common when a project is integrated via a subtree merge.
The git.git
repository has six root commits in its history graph (one each for Linus’s initial commit, gitk, some initially separate tools, git-gui, gitweb, and git-p4). In this case, we know that e83c516
is the one we are probably interested in. It is both the earliest commit and a root commit.
It is not so simple in the general case.
Imagine that libfoo has been in development for a while and keeps its history in a Git repository (libfoo.git
). Independently, the “bar” project has also been under development (in bar.git
), but not for as long libfoo (the commit with the earliest date in libfoo.git
has a date that precedes the commit with the earliest date in bar.git
). At some point the developers of “bar” decide to incorporate libfoo into their project by using a subtree merge. Prior to this merge it might have been trivial to determine the “first” commit in bar.git
(there was probably only one root commit). After the merge, however, there are multiple root commits and the earliest root commit actually comes from the history of libfoo, not “bar”.
You can find all the root commits of the history DAG like this:
git rev-list --max-parents=0 HEAD
For the record, if --max-parents
weren't available, this does also work:
git rev-list --parents HEAD | egrep "^[a-f0-9]{40}$"
If you have useful tags in place, then git name-rev
might give you a quick overview of the history:
git rev-list --parents HEAD | egrep "^[a-f0-9]{40}$" | git name-rev --stdin
Bonus
Use this often? Hard to remember? Add a git alias for quick access
git config --global alias.first "rev-list --max-parents=0 HEAD"
Now you can simply do
git first
[1]: https://stackoverflow.com/questions/5188914/how-to-show-first-commit-by-git-log#comment19763574_5189296 "tiho's comment" [2]: https://stackoverflow.com/questions/5188914/how-to-show-first-commit-by-git-log#comment19774504_5189296 "Chris Johnsen's remark"
Solution 3 - Git
You can just reverse your log and just head it for the first result.
git log --pretty=oneline --reverse | head -1
Solution 4 - Git
git log $(git log --pretty=format:%H|tail -1)
Solution 5 - Git
To see just the commit hash of the first commit:
git rev-list --max-parents=0 HEAD
To see the full git log
, with commit message, for just the first commit:
git log $(git rev-list --max-parents=0 HEAD)
To see all git log
messages in reverse order, from the first commit at the top (instead of at the bottom) to the last (most-recent) commit at the bottom (instead of at the top):
git log --reverse
References:
- How I learned the first command above: [the accepted answer] https://stackoverflow.com/questions/5188914/how-to-show-first-commit-by-git-log/5189296#5189296 (the 2nd command above was my own contribution)
- I learned about
git log --reverse
from the most-upvoted answer, by @Nyambaa
Solution 6 - Git
Not the most beautiful way of doing it I guess:
git log --pretty=oneline | wc -l
This gives you a number then
git log HEAD~<The number minus one>
Solution 7 - Git
git log --format="%h" | tail -1
gives you the commit hash (ie 0dd89fb
), which you can feed into other commands, by doing something like
git diff `git log --format="%h" --after="1 day"| tail -1`..HEAD
to view all the commits in the last day.