Skip to content

Branching and Merging

Dave Anderson edited this page Aug 10, 2013 · 28 revisions

Create a Branch

                             # master -> D234254; HEAD -> master 
git branch abranch           # master -> abranch -> D234254; HEAD -> master

Creates a new handle for referencing a commit-tree. By default, it will point to the same one your current working branch is pointing to.

Why Branch

A branch allows us to isolate changes and still have a reference to our master branch or any other important set of changes. We can quickly switch out and work on one set of changes and move back and work on that with ease.

Make the Branch Your Current Working Branch

git checkout abranch         # HEAD -> abranch

Replaces your folder's contents with the contents of the commit-tree that abranch references. Git's HEAD now points to this branch.

Note: any untracked files will remain and any staged files remain in the file cache.

Shortcut

                             # master -> D254644; HEAD -> master
git checkout -b abranch      # abranch -> master -> D254644; HEAD -> abranch

Creates a new branch and makes it the working branch.

Commit to the Branch

git add .                               # G343657 commit-tree created; G343657.parent -> D254644
git commit -m "Fixes for feature #35"   # abranch -> G343657

Here the same thing happens os any other commit. All the file and tree objects that were cached by the add command are pointed to by the branch file simply pointing to the commit-tree object. The only difference here is that HEAD points to abranch rather than master and it is abranch that is updating its hash and not master.

Merging

Fast-forward merging

                             # master -> D143424; HEAD -> master
git checkout -b abranch      # abranch -> master -> D143424; HEAD -> abranch
git add .                    # G154547 commit-tree created; G154547.parent -> D143424
git commit -m "abranch work" # abranch -> G154547
git checkout master          # HEAD -> master
git merge abranch            # master -> G154547

When the master branch has not changed since we branched from it, we simply change master branch to point to the commit-tree that abranch points to.

master -> A143421; HEAD -> master
abranch -> master -> A143421 

Composite merging

                             # master -> D143424; HEAD -> master
git checkout -b abranch      # abranch -> master -> D143424; HEAD -> abranch
git add .                    # G154547 commit-tree created; G154547.parent -> D143424
git commit -m "abranch work" # abranch -> G154547
git checkout master          # HEAD -> master
git add .                    # J154510 commit-tree created; J154510.parent -> D143424
git commit -m "master work"  # master -> J154510
git merge abranch            # N124512 commit-tree created; N124512.parents -> J154510, G154547;  master -> N124512

When the master branch has changed since we branched from it. Git finds the common ancestor between master and abranch, then applies changes to it.

D143424 common ancestor commit-tree

C143423 tree

hello.txt A153531
goodbye.txt B153532

``G154547`` abranch work commit-tree

F143426 tree

hello.txt E153535   hello is updated
goodbye.txt B153532

``J154510`` abranch work commit-tree

K143409 tree

hello.txt A153531
goodbye.txt I153548   goodbye is updated

``N124512`` merge work commit-tree

L143411 tree

hello.txt E153535     hello is updated
goodbye.txt I153548   goodbye is updated

The only thing the merge had to do here was switch out hash-references. There are more complex conflict-less merge possibilities, like if there were changes in the same file. But this gives a nice taste about how merges work.

Merging Conflicts

If there are conflicts, the process is much the same. Files with conflicts use a standard merge text within the file where there are conflicts.

Typical markup:

hello.txt

<<<<<<< HEAD:hello.txt
Hi.
=======
Hello.
>>>>>>> abranch:hello.txt

There are merge tools you can use.

git mergetool

or hand edit the file.

Squashing

git merge abranch --squash    # N124512 commit-tree created; N124512.parent -> D143424;  master (still) -> D143424

This will apply changes from abranch into your working branch, but not commit them. When you do commit, it will not include the history of commits you see in abranch.

Branch Management

git branch

Lists your branches

git branch -v

Lists your branches along with information on each branch's last commit

git branch --merged

Lists which branches have been merged into the current working branch already