452

I have a Git project which has a long history. I want to show the first commit.

How do I do this?

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Nyambaa
  • 38,988
  • 9
  • 29
  • 35

9 Answers9

637

I found that:

git log --reverse

shows commits from start.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Nyambaa
  • 38,988
  • 9
  • 29
  • 35
414

Short answer

git rev-list --max-parents=0 HEAD

(from tiho's comment. As Chris Johnsen notices, --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
Eldamir
  • 9,888
  • 6
  • 52
  • 73
Chris Johnsen
  • 214,407
  • 26
  • 209
  • 186
  • 55
    I believe ``git rev-list --max-parents=0 HEAD`` will do the same, and is a bit simpler. – tiho Jan 09 '13 at 18:33
  • 3
    @tiho: Yes, it does the same, and is simpler; though that option had not quite been [“invented”](http://git.kernel.org/?p=git/git.git;a=commit;h=ad5aeeded3295589b2573b143f754762a56f8f82) at the time of this question/answer. – Chris Johnsen Jan 10 '13 at 02:28
  • 1
    It occurs to me that first commit is more of a _leaf_ commit than a _root_ commit – tiwo Feb 06 '13 at 03:27
  • 1
    @tiho I think your answer should be its own answer and not just a comment. That way it will be more prominent and you will get much-deserved points. – Russell Silva Sep 23 '14 at 15:38
  • 1
    @RussellSilva I do not care about points, but I believe it is possible to edit other people's answers, which would probably be better than adding a new one. I'm not really comfortable doing it myself though, feel free to do it :) – tiho Nov 17 '14 at 21:19
  • One more addition, if there was no checkout, then the `HEAD` does not exist. But if there is was a fetch, then you have to use `FETCH_HEAD` may be with the path to the branch at the end of the `log` command. – Andry Sep 30 '19 at 10:05
  • Why have you answered a question asking specifically how to do this using git log with an answer using git rev-list? Has something been lost in edits to the question over the years? – Ash Nov 25 '20 at 05:09
  • Thanks! I've made a `first` alias with `!git log $(git rev-list --max-parents=0 HEAD)` – leogama Feb 04 '22 at 19:54
60

You can just reverse your log and just head it for the first result.

git log --pretty=oneline --reverse | head -1
Mohamed Mansour
  • 39,445
  • 10
  • 116
  • 90
25

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:

  1. How I learned the first command above: [the accepted answer] How to show first commit by 'git log'? (the 2nd command above was my own contribution)
  2. I learned about git log --reverse from the most-upvoted answer, by @Nyambaa
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
17
git log $(git log --pretty=format:%H|tail -1)
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
5

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>
MHC
  • 6,405
  • 2
  • 25
  • 26
  • 2
    Fails when there are merge commits (as a result of branching): `% git log HEAD~63 fatal: ambiguous argument 'HEAD~63': unknown revision or path not in the working tree.` – David Jones Jun 16 '21 at 17:10
2

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.

TankorSmash
  • 12,186
  • 6
  • 68
  • 106
1

If you want to get first commit with date, committer name and commit message, you will run this command.

git log master --pretty="%t %aD %aN %s"| tail -1

ttree hash , ad refer to author name, aN refers to author name and s for subject.

If you want to get first commit with branch that make from master branch(copy from master), you will refer to master and other branch.

git log master...docs --pretty="%t %aD %aN %s"| tail -1
Eng_Farghly
  • 1,987
  • 1
  • 23
  • 34
0

You can get the same result as the accepted answer with less typing:

$ git fsck  --root
root 3fa77c58f85c591f9c6a1b0510228e4aec704697
Checking object directories: 100% (256/256), done.

This works because the first commit of most git repos is the root node.

Mike Slinn
  • 7,705
  • 5
  • 51
  • 85