Please see the image of the environment in gitlab
There is a commit version 8d6995e4 in our case. I am doing git log | grep and cannot find this commit version. What this string indicates?
2 Answers
TL;DR
When you run git log
you tell it which commit to start with. If you don't tell it, it assumes the current commit from the current branch. It finds the rest of the commits that it can find from that starting-point. You have commit 8d6995e4
in your repository, but it's not on your current branch.
You might use git log --all
to tell it to start from all the recorded starting-points (branch names, tag names, remote-tracking names, and so on), and you might want to Get Help From A Dog, or as OznOg suggested, use a visual viewer. See also Pretty git branch graphs.
Long
To understand what's going on here, you need to understand commits—which are Git's raison d'être—and how Git finds them, usually starting from branch names. This gets into the idea of reachability in a graph, which is explained in an even longer and more thorough way at Think Like (a) Git.
Commits
Every commit has its own unique hash ID. That's that big ugly string you see here, 8d6995e4
(though in fact it's much longer—40 characters of apparently-random junk, and not actually random at all). That hash ID is the "true name" of the commit: it's how Git finds the commit, in the database of "all commits ever" (to which the main thing people do is add more commits).
Every commit also holds a parent commit hash ID. That is, the child of some parent commit remembers the parent's hash. Parents do not remember their children because once a commit is made, nothing inside it can ever change. This frozen-ness of commits does not matter for git log
but does matter for many other Git commands.
The above is a slight exaggeration, because, at least one commit—the very first one someone makes in a new and empty repository—has no parent. The parent of this commit is the commit that comes before this commit. The first commit has no commit that comes before it. And, merge commits have more than one parent, which is what makes them merge commits.
What all this means is that commits form a backwards-looking chain. It's this backwards chain that git log
uses. Here's a simple drawing of a repository with just three commits, where instead of big ugly 40-character hash IDs, I use just one uppercase letter. Obviously we'll run out pretty fast–the repository will be full at 26 commits—so this is not the way Git does it, but it does illustrate the issue just fine. Our very first commit is A
, which has no parent. Then we make B
which gets A
as its parent, and last, we make C
which gets B
as its parent.
A <-B <-C
Because nothing inside a commit can ever change, we can draw the connections that go backwards from child to parent as lines that go both ways, as long as we remember that Git has to go backwards. This is more convenient for me in StackOverflow postings, because I also sometimes need to do diagonals:
A--B--C
\
D
and I have no convenient text arrows that work for everyone here.
Branch names point to commits, but also move
Now, for git log
to work, you must give it a starting commit—a hash ID. In fact, for very many things in Git to work, you have to give them a hash ID. But real hash IDs are big and ugly (8d6995e4
) and apparently-random. They are definitely not in a sensible order, and there is no way for humans to remember them. So what we do is we pick out a branch name, such as master
. We have Git shove the hash ID of the last commit into the branch name, which means our drawing now looks like this:
A--B--C <-- master
The name lets Git find the last commit, in this case C
. From there, git log
walks backwards to B
, and then back to A
, and then since A
has no parent, Git can finally stop.
To add a new commit, Git will package up whatever it is you are committing—a new snapshot—and add metadata like your name and email address, the current time, and your log message. Git will automatically add to the metadata the hash ID of the current commit. Git writes all of that into the object database, and the act of writing it assigns this new commit its unique hash ID. That, of course, is some other big ugly number, but we'll use the letter D
:
A--B--C <-- master
\
D
To rememeber that D
is our last commit, Git now updates our name master
:
A--B--C
\
D <-- master
So now git log
will start at D
, then show C
, then B
, then A
.
Using your HEAD to change what you see and update
It's the commits that matter. The branch names are there to help us find them. But what happens when we have several branch names? Let's look at a slightly more complicated graph, after we've made a few more commits:
...--C--D <-- master
\
E--F <-- develop
We said above that when we make a new commit, Git moves the branch name. But how does Git know which branch name to move? If we had:
...--C--D <-- develop, master
—and we probably did at some point—how does Git know, when we make commit E
, that it's develop that should move, and not master
?
The answer is that we use git checkout
to attach the special name HEAD
to just one branch. If we pick develop
, we get:
...--C--D <-- develop (HEAD), master
Then when we add commit E
, Git moves develop
:
...--C--D <-- master
\
E <-- develop (HEAD)
The name HEAD
stays attached to the branch name, even as the branch name itself moves. (The actual implementation of this, for those who are curious, is that there is a file in .git
named HEAD
, that simply contains the branch name itself. So the contents of HEAD
only change when you pick a new branch to use. The contents of the branch name—the hash IDs for the latest commit for master
and develop
—are stored elsewhere, in one or more of various different places.)
Note, by the way, that in the drawings here, commits A-B-C-D
are on both branches. Commits E-F
are only on develop
. But since we can move branch names, we could change this by moving master
to point to F
. That would make all six commits be on both branches. We do not have to change the commits to do this, which is necessary, since we can't. :-)
Graphs can get much more complicated. Rather than showing a very complicated one (like the one you probably actually have), here's a simpler one that shows what happens when we commit a merge. Here's the before picture:
I--J <-- release (HEAD)
/
...--G--H
\
K--L <-- develop
and the after one:
I--J
/ \
...--G--H M <-- release (HEAD)
\ /
K--L <-- develop
The new merge commit M
is only on release
. It has two parents, J
and L
. Commit J
is only on release and it has one parent I
. Commit L
is on both branches and it has one parent K
. Both I
and K
lead back to commit H
, which is on both branches, and that leads back to G
, which is on both, and so on.
This is where git log
comes in
If you run git log
without giving it some starting commit, Git looks at your HEAD
to find your current commit. Your current commit is the one your branch name points to. You mention in a comment that you are on your release
branch and that it points to a merge commit. So your picture probably looks something like what we just drew.
The git log
command will start from commit M
and show it to you. Then it adds all of M
's parents to the list of commits it needs to show. It must now try to show you both J
and L
at the same time. It can't, so it picks one of these two to show. Then it adds the parent of whichever one it showed, to its list of things to show.
If it just showed J
, git log
now has two commits to show you at the same time, namely L
and I
. It can't show both at the same time, so it picks one. Then it adds that one's parent to its list, and so on.
The git log
command will intermingle the commits from the two sides of the merge, by default. In particular, it shows them one at a time based on the time stamp, so that you see the newer ones first. If J
is newer than L
you'll see J
before L
, but if L
is newer than J
you'll see L
first. The same goes for I
and K
(vs both L
and J
). But git log
does respect the shape of the graph in that no matter what else it does, it won't show H
until it's finished showing I-J
and K-L
.
Eventually, it will be able to show H
, and when it does the list of other commits to show will be empty. It will show H
, add H
's parent G
to the list to show (which now has just one entry), then show G
and add G
's parent, and so on.
But git log
won't show commits it cannot get to by starting at M
and working backwards!
I--J
/ \
...--G--H M <-- release (HEAD)
\ /
K--L <-- develop
\
N--O--P <-- another-name
Suppose there's some other name remembering a hash ID P
. This might not be a branch name: maybe it's a name like origin/develop
or origin/master
, that your Git uses to remember branch names your Git saw in some other Git.
Running git log
won't show commit P
. Having not shown P
it won't move back to O
either. Git literally cannot go from L
to N
. It can only go from N
to L
, backwards. You need to pick a starting commit hash that start at or beyond the commit you care about, to see the commit you care about.
Note that commits N-O-P
here are not "on" release
. We use the word "on" to mean "commits reachable from the tip". The tip of release
is commit M
and commit N
cannot be reached by going backwards from M
.
Note that commit M
cannot be reached by going backwards from N
either! Two commits can have a common ancestor without themselves having a parent/child or grandparent/grandchild relationship. The fact that they have a common ancestor may only make them siblings or cousins.

- 448,244
- 59
- 642
- 775
you are probably not up to date or on the wrong branch. try directly the sha1
git log 8d69
after a git fetch --all

- 4,440
- 2
- 26
- 35
-
Interesting, when I use this command git log 8d6995e4 I see the log starting from 8d6995e4n and later. However, git log | grep 8d6995e4 . gives nothing. So, what 8d6995e4 indicates? – Alex Feb 03 '19 at 13:21
-
this indicates that git knows about this sha1 but that you are probably not on the right branch. Try checking out the right branch (from the name you have on gitlab) (`git checkout 'branch_name'`) – OznOg Feb 03 '19 at 13:23
-
I can see the description: Merge branch 'release' into 'master'. I am on the release branch – Alex Feb 03 '19 at 13:27
-
if you see merge release in master, you should probably be on master. Maybe you should use some visual tool like gitk or tig to help you figure out all this – OznOg Feb 03 '19 at 13:31