I want merge to exactly the same!
That's not what git merge
does.
Step back for a moment and consider that the goal of git merge
is to combine work. Suppose that you and some other guy—let's call him Fred—start with the all the same files. One of them is some file that uses //
comments.
Fred changes some code down at line 55. Meanwhile, you notice that there's a mis-spelling in a comment:
// some tuxt
should read:
// some text
and, perhaps, should be indented differently. So you fix line 12.
Now, at some point in the future, you obtain Fred's commits. You run:
git diff <mine> <fred>
or:
git diff <fred> <mine>
One of the things that shows up different is the comment-fix you made. If git merge <fred>
simply made your file the same as Fred's, that would undo your spelling fix. Hence, git merge
does not use the result of git diff
of the two branch tip commits.
So, what does git merge
use?
Git's merge operation depends on finding the merge base. The merge base is, essentially, the common commit that you and Fred both started with. Finding the merge base is a matter of examining the commit graph.
The commit graph emerges by the fact that each commit has a parent commit.1 The parent of your current commit is the one that was in place just before you, or whoever, made your current commit. That commit's parent is the one that was in place before it, and so on. Git works by following these backwards-pointing parent chains. For (much) more on this see many of my other answers to similar merge questions.
In particular, though, you ran:
git merge master
and got:
Already up to date.
This particular message occurs when your branch is ahead of master. That is, suppose the commit graph looks like this:
... <-F <-G <-H <-- master
\
I <-J <-- development (HEAD)
Your current commit is commit J
(J
here stands in for the big ugly hash ID), whose parent is commit I
, whose parent is commit H
. So if, in our little "combine work" setup, master
represents Fred's latest work, and development
represents yours, then the command: Combine Fred's work with mine is trivially satisified: you both started with Fred's latest, commit H
. You made some changes since then. Git just keeps exactly what you started with.
1Some commits have two parents. These commits are slightly special, in that they are merge commits. At least one commit in the repository has no parents, because it was the very first commit and could not have a parent.
Viewing the commit graph
There are many ways to view the commit graph, including with various GUIs, or the tcl/tk based viewer gitk
that comes with Git. These tend to be better, in some ways, than the text-graph viewer built directly in to Git, but that viewer is always present and does not depend on external software the way these graphical viewers do.
Run git log --graph
and Git will generate a graph. Because git log
output is long, you won't really see very much on a page, so you might want to instruct git log
to use one line per commit:
git log --oneline --graph
That will show you the graph starting with your current commit and working backwards. To make sure that Git tells you that the first commit is your current commit, you may want to add the --decorate
option, or turn on log.decorate
in your configuration:
git log --decorate --oneline --graph
(or git config log.decorate auto
, which implies --decorate
automatically when using git log
at the command line). And, to tell Git to start working backwards from all branches and all tags, you may want to add --all
:2
git log --all --decorate --oneline --graph
Or in this particular case you might use:
git log --decorate --oneline --graph master develop
to tell Git: starting from both master
and develop
, show me commits along with their parent relationships. That will let you view the graph, and will inform you (somewhat, at least) about what Git will see as the merge base between master
and develop
.
2"All Decorate Oneline Graph" is a very useful combination, and can be remembered via the mnemonic: get help from A DOG, from Pretty git branch graphs.