setia_'s answer remains the most appropriate but your question is meaningful because a git history can be considered from two distinct perspectives: either you totally view it as a (mathematical) graph in which parent's order is supposed to be non significant, OR you consider a merge operation as the integration of an external branch into a common trunk (i.e. your current branch, very often "master"). This is also the assumption made by git merge
.
This is important not only because browsing an exponentially growing tree rapidly becomes a pain, but also because having a branch "master" that contains a finished product and integrating external submissions is a model followed by many workflows.
Since both these points of view are valid, they cause --first-parent
to be a frequently used option, though not a main command nor a default behavior.
For example, browsing the Linux kernel main repository (for which Git was first designed) with a simple git log --graph
can take up to one minute before displaying something, but git log --graph --first-parent
will show you the main branch and let you observe that it's mainly composed of merges, with occasional direct commits.
Another thing one have to keep it mind is that you can ask to have your commits displayed by chronological order using --date-order
or topological order with --topo-order
. Let's assume you have two distinct branches and alternatively commit to the one or the other before eventually merging them. Depending on the order, the resulting graph would look like one of these :
Chronological order Topological order
* ec9a124 Merge branch 'B' into A * ec9a124 Merge branch 'B' into A
|\ |\
* | e5314f2 Ninth | * e3e2435 Eighth
| * e3e2435 Eighth | * af3bac5 Sixth
* | 308228b Seventh | * 3a2f0b9 Fourth
| * af3bac5 Sixth | * d901c9f Second
* | ab11578 Fifth * | e5314f2 Ninth
| * 3a2f0b9 Fourth * | 308228b Seventh
* | 344bd0f Third * | ab11578 Fifth
| * d901c9f Second * | 344bd0f Third
|/ |/
* 0f029bc First * 0f029bc First
All commits remain on their respective line but the latter is a depth-first search. And since git log
(so does git rev-list
) displays a collection of pre-gathered revisions, this order will be the same whether you're using --graph
or displaying them as a flat list (actually, if not specified, git log
use reverse chronological order by default, and topological one when using --graph
).
Because of that, you can't simply rely on the first row to decide which parent to choose.
This can also cause some older commits to appear before the new ones, which can be very confusing when beginning with Git, and give you the impression that your work has disappeared (until it comes to one's mind to perform a search, then retrieve it buried somewhere in history).
git log
by default shows the entire ancestry in order by birthdate (where timestamp weirdities don't make that contradict ancestry). Try it withgit log --oneline --graph --decorate --first-parent
. – Wesle^
or^1
means the first parent.^n
means the n-th parent. So when it comes to4c9749e
, it'sHEAD^^^2
. If a merge commit is created after merging B to A, A's original head is its first parent and B's head is the 2nd parent. – Incestuousgitk
is usually a nicer alternative tolog --graph
, the graph is a bit more readable than ascii one, and it can show a lot of details, like the list of parents if selected commit. – Conduplicate