Reputation: 3670
On running git log
i am seeing strange graph. I will explain it further.
Below is the output for git log with graph.
$ git log --graph --oneline
* df1834d (HEAD -> master, tag: r-0.1, origin/master) Merge branch 'master' of https://github.com/samshers/graphql-hibernate
|\
| * d56a675 fixed country null issue
* | ee9bb70 fixed country null issue
|/
* 2617f2a hibernate cascade error issue. country field in state table set to null
As you an see master has two separate branches in itself. To confirm this further, i ran
$ git branch --contains ee9bb706c8fcc329fac4acf69ad6b684f1069170
joincolumn_issue
ls
mappedBy
* master
And then
$ git branch --contains d56a6751771b1f62d9ceb0bcce9a2391c004ee44
joincolumn_issue
ls
mappedBy
* master
So clearly these two commits are present on master - so then why are there two graphs. How can i know if changes both the commits are present on master. Or if only changes from one of them is actually present on the master, which one of the two?
Edit - following responses from RY and Mark
( if color codes add any further meaning, please hint on that as well.)
So, am further trying to understand why a commit (Y) is not based on previous commit (X) ( if X was committed before Y).
The git log shows that both d56a675
and ee9bb70
where committed at the same time.
commit ee9bb706c8fcc329fac4acf69ad6b684f1069170
Author: itsvamshers <[email protected]>
Date: Mon Sep 9 17:24:01 2019 +0530
fixed country null issue
commit d56a6751771b1f62d9ceb0bcce9a2391c004ee44
Author: itsvamshers <[email protected]>
Date: Mon Sep 9 17:24:01 2019 +0530
fixed country null issue
But, on digging further the little difference can be seen..
$ git show -s --format="%ct" d56a6751771b1f62d9ceb0bcce9a2391c004ee44
1568030041
and
$ git show -s --format="%ct" ee9bb706c8fcc329fac4acf69ad6b684f1069170
1568031643
and this info should be enough for git to put the commits in right order. But if it is not, then I guess it is smarter and doing it for reason, just trying to understand the reason and the cause.
Upvotes: 0
Views: 782
Reputation: 45659
It sounds like the confusion is about what a branch is, and what it means for a branch to "contain" a commit in git.
A branch is just a pointer to a commit. A branch is not a collection of commits in git, like it may be in some tools. The closest thing git has to a branch "containing or not containing" a commit is, a commit either is or is not "reachable" by that branch. The commit the branch points to is reachable, as is any commit found by following a reachable commit's parent pointers (recursively).
A merge is a commit with two (or more) parent pointers. So when you merge a branch into master
, all of that branch's commits become reachable from master
(via the merge commit's second parent pointer). So the branch commits are "contained in" master (i.e. reachable from master) because you merged them into master; this is normal git behavior.
If you want to know only the commits that were "on master" when committed... well, git doesn't really keep track of things like that, but you can do
git log --graph --one-line --first-parent
Now, if you do unusual things (like merging master into a branch and then fast-forwarding master onto the resulting merge, as just one example) then this still may not do quite what you intend; but if you follow a reasonably normal branch/merge strategy (and stick to "porcelain" commands - those intended for end-user use), it should look more like what you're expecting.
This behavior of log
by default following both branches that came into a merge is the main reason the --graph
option is useful IMO.
Regardless, the changes from all commits shown in your example graph are present in master, because they're all shown as reachable from master. There is a gotcha - this assumes that the merge commit is a reasonable merge of the two branches. If you merged with the ours
merge strategy, then the branch is not present. If you did something really weird with conflict resolution that undid some changes from a branch, then you have what is sometimes called an "evil merge" and the change it undid is not present. If you know nobody on your team does such things, then you don't need to worry about that.
You can rely on git log
's history simplification to tell you if a branch was completely clobbered in a merge (such a branch should not be shown unless you give options like --full-history
, because log
will decide that it can fully explain the current state without mentioning the branch), but this may not be 100% reliable and in any case nothing in log
's logic can tell you if you have an evil merge - so at some point, you have to rely on the idea that you and your team follow reasonable processes.
Or good tooling and test coverage; you also could rely on that.
Upvotes: 1
Reputation: 224904
d56a675 isn’t present in the history of ee9bb70, and ee9bb70 isn’t present in the history of d56a675. Both are present in the history of master, because they were merged back together in df1834d. All of this is why the graph has a fork in it.
Both of their changes exist in the history of master, but that doesn’t mean the merge commit preserved those changes the way you might want. You have to look at the current state and compare.
git show d56a675
git show ee9bb70
git diff 2617f2a..df1834d
Also, if both commits are the same or if one is a newer version of the other (which their summary suggests), merging them is probably a mistake.
Upvotes: 1