Tirafesi Tirafesi - 1 month ago 10
Git Question

Git merging - What happens to the merged branch?

I have a question regarding git merging. Let's say I have two branches in my repository (both local and remotely): master and test. And while I was working on the test branch, the master branch got updated by some else. In the terminal, I write:

git checkout master
git pull origin master


And this updates my master branch with the recently added stuff right? Then, I finish what I was doing in my test branch.

If I go to the terminal and write:

git checkout master
git merge test
git push origin master


This merges my test branch into my master branch and then pushes the changes to github right (let's assume there are no conflicts)? My question is: what happens to the test branch? Does it stay the same way it was before the merge? Or do both the test and the master branch become the same? Should I do this now to update the test branch?

git checkout test
git pull origin master
git push origin test


Thanks in advance.

Answer

If I go to the terminal and write:

git checkout master
git merge test
git push origin master

This merges my test branch into my master branch and then pushes the changes to github right (let's assume there are no conflicts)? My question is: what happens to the test branch?

Nothing at all.

Remember that branch names are simply names for a (single) commit. To draw them, I like to draw the commits themselves as round o nodes, or uppercase single letters when we need to talk about specific commits, with lines connecting them:

...--o--o--o--o      <-- master
         \       
          o--o--o    <-- test

Each commit "points back" to its parent commit—so if we give each of these commits a letter name, and draw in all the intermediate arrows, we get:

...<-A<-B<-C<-D      <-- master
         \
          E<-F<-G    <-- test

The branch names, master and test, actually contain the raw hash IDs of the tips of the two branches. That is, if you examine the file .git/refs/heads/master1 you'll find one of those big ugly 40-character hashes, a139fc7... or whatever, inside it.

In effect, master points to commit D, and test points to G. Commit D points back to commit C, which points back to B, and so on; and commit G points back to F, which points back to E, which points back to B (it's too tricky to draw an arrow with plain text here, since some good arrow-drawing fonts only work on some machines).

When you're on some branch and make a new commit, the way Git makes this commit is that it writes the new commit with its parent set to the current branch-tip, and then once the new commit is safely in the repository, rewrites the branch name file with the new commit's ID. This makes the branch name point to the new tip. The new ID goes nowhere else, so no other branch names change in any way.

A merge commit has two parents, so when you git merge test and it works, you get this:

...--o--o--o--o---o  <-- master
         \       /
          o--o--o    <-- test

Note that test has not moved at all, but master has—and the new merge commit points back to two different earlier commits: the old branch-tip of master, and the (unchanged) tip of test.


1There's no promise that this file will exist in the future, or stay in this location or have this format, but right now, with today's Git versions through 2.10, you will generally have that file.

Comments