Reputation: 683
To get the git branch hierarchy, I issue the following command to my git repo:
git log --all --graph --decorate --oneline --simplify-by-decoration
However, I get a confusing result:
* 023448b (I) Comments
| * 7b08b45 (H) Comments
|/
| * 379334c (G) Comments
| * ec95b66 (F) Comments
|/
| * dca9a7b (E) Comments
|/
| * f7bb48a (D) Comments
|/
| * 82224b2 (C) Comments
|/
* c7887dd (HEAD, master, A, B) Commments
* 5046cbf Initial Commit: Comments
The last but one line shows three branches. Isn't it supposed to show only the master
? Also what is the meaning of the last sentence?
Upvotes: 0
Views: 138
Reputation: 487993
I don't know what you mean by "the last sentence", but:
Isnt it supposed to show only the Master?
No. You said --all
. All means all: all branches, all tags, and all other references as well. If you only wanted to look at branch master
you should have said master
.
The way git log
finds commits to show is to start from some set of references and then examine each commit those references point-to, then look at those commits' parent commits, then look at the parents' parents, and so on. This "walk" through history—looking at each commit's parent or parents, and queuing those commits for further examination—simply starts from the specified points, and continues until there are no more commits. Commits "run out" whenever this process reaches a root commit, which is a commit with no parents.1
The default for git log
is to start from the name HEAD
, unless you name some other starting point(s). You did that: you said --all
, which means all starting points (except reflogs).
Meanwhile:
--simplify-by-decoration
directs git log
to skip commits that do not have some branch or tag name pointing to them. However, for whatever reason, this never2 skips a root commit. And:
--decorate
directs git log
to put the names of any branches and/or tags that point to that commit, on any commits shown (which of course are those retained by --simplify-by-decoration
, except for root commits). Hence if you replace --all
with master
, you should expect to see:
* c7887dd (HEAD, master, A, B) Commments
* 5046cbf Initial Commit: Comments
since the names HEAD
, master
, A
, and B
all point to c7887dd
(which is retained because a name points to it), and 5046cbf
is a root commit (which is retained because it is a root commit).
1Note that this only stops adding more commits to the queue of "commits to examine". If the queue already has many queued commits, the process goes on to examine those. If there are multiple root commits in the graph, this process may find several or all of them (depending on where you start the traversal).
Both git log
and git rev-list
do breadth-first traversal of commit nodes within the graph, but both also sort the commits. Adding --graph
forces the sort to use a topology-respecting order, in which no parent commit is shown until all its children have been shown (when working in the normal "backwards" direction, that is).
2A cursory re-check of the source code suggests that this is not quite true: root commits will be discarded if they have an empty tree attached. This check happens after modifying the attached tree based on any pathspec arguments given to git log
or git rev-list
, so you won't see root commits when looking for commits that modified some particular file. In this case there are no pathspecs, so you will only not-see the root commit if it is literally empty (refers to the empty tree).
Upvotes: 1