How to reference the initial commit?
Asked Answered
T

6

167

I've got a script that needs to reference the initial commit in a repository. git has the special reference HEAD, but doesn't have the corresponding TAIL. I cannot find anything in git help rev-parse that would seem to help me.

Here's what I'd like to do:

git show TAIL

Here's one option I have:

git show `git log --reverse | if read a commit ; then echo $commit ; fi`

That's pretty hacky and depends on the output of git log not changing.

Right now I just tag the initial commit and use that as my refspec. However, I'd like to release a general tool, so that's not a great option.

Twylatwyman answered 17/6, 2009 at 12:43 Comment(0)
S
187

Do not use git-log for scripting: use either git-rev-list, or git-log with specified custom format (--format=*<sth>* option).

There is additional problem with your question: there can exist more than one such TAIL root commit (parentless commit) in a repository (even if we discount disconnected branches, such as 'html', 'man' and 'todo' in git.git repository). This is usually result of joining separate projects in one, or using subtree merge of separately developed subproject.

For example git repository has 6 root commits: git-gui, gitk (subtree-merged), gitweb (merged in, no longer developed separately), git mail tools (merged very early in project history), and p4-fast-export (perhaps accidental). That is not counting roots of 'html and 'man' branches, "convenience" branches which contains pre-generated documentation, and 'todo' branch with TODO list and scripts.


If you have git 1.7.4.2 or newer, you can use the --max-parents option:

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

Otherwise, you can get list of all parentless (root) commits accessible from current branch using:

$ git rev-list --parents HEAD | egrep "^[a-f0-9]{40}$"
Sunbathe answered 17/6, 2009 at 14:51 Comment(2)
For me, the git rev-list HEAD | tail -n 1 and git rev-list --max-parents=0 HEAD are not returning the same hash value for me. The one using the --max-parents=0 is in fact getting the initial commit though. Just thought I would point out that the latter seems more reliable.Uranalysis
@Treebranch this could happen if you have commits with odd timestamps. adding --topo-order to the rev-list should fix that, though I think the --max=parents=0 answer is best.Panicle
C
44

git rev-list HEAD | tail -n 1 is a more stable option.

Caulfield answered 17/6, 2009 at 12:54 Comment(3)
This would return one of tail commits; there can be more than one root (parentless) commitHouston
This answer worked perfectly and only returned one commit sha whereas git rev-list --max-parents=0 HEAD returned 3 commits.Pasteurism
tail is also not a command that's there by default in windows - works in GitBash on windows though. :)Rueful
F
14

Not sure what you're trying to do here, but some git commands take --root as an option, in order to reference the root of the commit tree, e.g.

git rebase --interactive --root main
Fivestar answered 14/8, 2020 at 15:5 Comment(0)
B
7

Assuming the first parent of a merge is the main line of development:

git rev-list --reverse --topo-order --first-parent HEAD | sed 1q
Bazil answered 12/2, 2021 at 17:59 Comment(1)
If i could award bonus points for using sed instead of head then I would. sed 1q can be pointlessly shortened to sed q by the way.Raseda
D
2

Taken into account there could be multiple initial (orphan) but those commits still reachable from any of the refs it's possible to use:

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

or

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

But if it's required to find root commits including non-reachable ones, git fsck could be used:

git fsck --root --no-dangling

The --no-dangling option suppresses warning messages about dangling commits making it easier to process output in scripts.

Dusk answered 14/6, 2022 at 11:41 Comment(0)
G
1

To get first commit on the repository, run this command:

 git rev-list --oneline HEAD | tail -n 1
Gladysglagolitic answered 11/12, 2022 at 8:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.