Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does git handle commits in a merge?

I'm having trouble understanding how a git merge works in terms of the commits created by the merge process. I've read the relevant sections in pro git and the git community book, but am still confused.

Consider this scenario: I have an "origin" git repo:

          master
            |
a0--a1--a2--a3
  \
   -b0--b1
         |
      branch2

I clone this repo to a local repo and then work only on the local repo. In branch2, I did a "git merge master". Now my local repo looks like this:

     master / origin/master
            |
a0--a1--a2--a3
  \           \
   -b0--b1-----merge
         |       |
  origin/branch2 |    
              branch2

So the merge created 1 commit, "merge", after the "b1" commit. "git log" for branch2 shows the expected graph:

> git log branch2 --graph --pretty=oneline --decorate
*   a7b69fc6759e1dd5463bab379ce101a6ad026c7b (HEAD, branch2) Merge branch 'master' into branch2
|\  
| * 482e4026f05e33395a9fc3c87f50a746f692406a (origin/master, origin/HEAD, master) a3
| * 8de57bdea2d316073af3b7055f8c28c56004ce94 a2
| * 1e991047996aad269f2c01b9a0b9a7d8293096a1 a1
* | 99955f66843df51fb9d40c7797156c32cad57415 (origin/branch2) b1
* | 30ca9b6363558322f2bb7810d75cda0d9c2ba3e0 b0
|/  
* 76a7c6d0eb54a9580841115ff2c3429360ab2ac9 a0

In addition, if I go one commit before the current head, I get to the b1 commit, as expected. (follow the branch2 line in the graph and go back 1 commit)

> git log branch2~ --graph --pretty=oneline --decorate
* 99955f66843df51fb9d40c7797156c32cad57415 (origin/branch2) b1
* 30ca9b6363558322f2bb7810d75cda0d9c2ba3e0 b0
* 76a7c6d0eb54a9580841115ff2c3429360ab2ac9 a0

Here comes my confusion. I haven't pushed my changes to the origin yet, but when I do a "git status", git says my local branch2 is ahead of the origin/branch2 by 4 commits. I thought the merge only resulted in 1 new "merge" commit, as seen by the graph / diagrams above? Why 4?

> git status
# On branch branch2
# Your branch is ahead of 'origin/branch2' by 4 commits.
#
nothing to commit (working directory clean)

Also, doing a "git log" from origin/branch2 to branch2 shows the 4 commits instead of the 1 I expected (going from "b1" to "merge").

> git log origin/branch2..branch2 --graph --pretty=oneline --decorate
* a7b69fc6759e1dd5463bab379ce101a6ad026c7b (HEAD, branch2) Merge branch 'master' into branch2
* 482e4026f05e33395a9fc3c87f50a746f692406a (origin/master, origin/HEAD, master) a3
* 8de57bdea2d316073af3b7055f8c28c56004ce94 a2
* 1e991047996aad269f2c01b9a0b9a7d8293096a1 a1

I understand the 4 commits are the 3 from master (a1,a2,a3) that the merge is supposed to bring over to branch 2, plus the "merge" commit. But why doesn't the graph show it that way? If it does, it would look like:

     master / origin/master
            |
a0--a1--a2--a3-----------
  \                      \
   -b0--b1--a1'--a2'--a3'--merge
         |                  |
  origin/branch2            |    
                         branch2

And branch2~ would bring me to a3' instead of b1.

Thanks in advance for any help.

like image 306
digitalsky Avatar asked Jun 17 '11 22:06

digitalsky


1 Answers

As mentioned in "How to get the changes on a branch in git":

git log origin/branch2..branch2

means: all the commits on branch2 (positive reference) which aren't on origin/branch2 (negative reference)
(On the positive and negative references, see "Difference in 'git log origin/master' vs 'git log origin/master..'")

In your case, after the merge, you do have 4 commits on branch2 (the local one) that aren't on origin/branch2: a1, a2, a3 and merge.

like image 132
VonC Avatar answered Sep 21 '22 01:09

VonC