Git branching, merging & rebasing (Spoon-Knife repo example)

This post will go over some examples for branching, merging and rebasing using GitHub’s Spoon-Knife repository.

Fork & Clone repository

  1. Fork the Spoon-Knife repository from GitHub
  2. Clone repository to local computer:
    git clone https://github.com/lkisac/Spoon-Knife.git
    Confirm that we are on the master branch:
    git branch
  3. Create a new file called name.txt with first name in it:
    vi name.txt

    Len Isac
    
  4. Add and commit the name.txt file to Git:
    git add name.txt
    git commit -m "added name.txt file with first name"
  5. Confirm that you have 1 new commit on the master branch:
    git log

    commit d87e3b4dc4a9497d68fcbbfe3247409225d4a959
    Author: Len Isac Seneca <len_isac@hotmail.com>
    Date:   Sat Feb 4 10:48:55 2017 -0500
    
        added name.txt file with first name
    
  6. Since we would like to do this work on a new branch instead, we’ll create a new “name” branch, and merge it back into master later:
    git checkout -b name
    Confirm we are on newly created “name” branch:
    git branch
    Check to see that the master and name branch both point to the same commit:
    git show name
    git show master

    Since we created the “name” branch from inside the “master” branch, git will create the new branch pointing to master’s commit (“added name.txt file…”).
  7. Move the master branch back one commit:
    git checkout -B master HEAD~1
  8. Check that both branches are pointing to different commits now:
    git show name
    git show master

Merging

  1. Create third branch named “fav-food” from the master branch.
    git checkout -b fav-food
  2. Create food.txt file with a list of favourite foods
    vi food.txt

    Spaghetti
    Toast
    Beef curry
    
  3. Add and commit
    git add food.txt
    git commit -m "added food.txt - list of favourite foods"
  4. Create fourth branch named “name-and-food” from the name branch commit. Since we are inside the fav-food branch but want it to point to the “name” branch’s commit, we need specify it in the second parameter:
    git checkout -b name-and-food name
    Confirm new merge commit “Merge branch ‘fav-food’ into name-and-food”
    git log --max-count=1
    git ls

    We can also see now both the food.txt and name.txt files exist in this branch.

Merge conflicts

To demonstrate merge conflicts, 3 branches that contain the same “animals.txt” file will be created.

  1. Create “animals” test branch from master:
    git checkout -b animals master
  2. Now we’ll create an “animals.txt” file with 3 farm animals.
    vi animals.txt

    cow
    lamb
    horse
    
  3. Add & commit:
    git add animals.txt
    git commit -m "added animals.txt"
  4. Create a second “water-animals” branch pointing to the animals branch commit:
    git checkout -b water-animals
  5. Edit the “animals.txt” file and add 3 water animals:
  6. vi animals.txt

    cow
    lamb
    horse
    dolphin
    whale
    seahorse
    
  7. Add & commit:
    git add animals.txt
    git commit -m "added three water animals to animals.txt
  8. Create a third branch named “jungle-animals pointing to the animals branch commit:
    git checkout -b jungle-animals animals

  9. Edit the “animals.txt” file and add 3 jungle animals:
  10. vi animals.txt

    cow
    lamb
    horse
    tiger
    lion
    bear
    
  11. Add & commit:
    git add animals.txt
    git commit -m "added three jungle animals to animals.txt
  12. Switch to animals branch and merge water-animals into it:
    git checkout animals
    git merge water-animals

    animals.txt now contains the three water animals added in the water-animals branch.

    Updating b11d23a..3fce797
    Fast-forward
     animals.txt | 3 +++
     1 file changed, 3 insertions(+)
    

    Since the branch was ahead by 1 commit, git performs a fast-forward, which aligns the current branch with the branch being merged. git log shows its commit message, not the merge commit message this time.

  13. Now we’ll try merging the “jungle-animals” branch into animals
  14. git merge jungle-animals

    Auto-merging animals.txt
    CONFLICT (content): Merge conflict in animals.txt
    Automatic merge failed; fix conflicts and then commit the result.
    

    git status shows us that we have unmerged paths and need to fix conflicts, then run “commit”.

  15. Fix merge conflicts
  16. vi animals.txt

    cow
    lamb
    horse
    <<<<<<< HEAD
    dolphin
    whale
    seahorse
    =======
    tiger
    lion
    bear
    >>>>>>> jungle-animals
    

    HEAD (animals) and jungle-animals both use the same lines but have different contents. We have to choose which one we want or if we want both, then remove the conflict markers. If I simply remove the conflict markers, I can keep the contents from both branches making it six lines instead of three.

    cow
    lamb
    horse
    dolphin
    whale
    seahorse
    tiger
    lion
    bear
    
  17. Add the fixed file and commit the merge
  18. git add animals.txt
    git commit

    Merge branch 'jungle-animals' into animals
    
    Conflicts:
        animals.txt
    #
    # It looks like you may be committing a merge.
    # If this is not correct, please remove the file
    #   .git/MERGE_HEAD
    # and try again.
    
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # On branch animals
    # All conflicts fixed but you are still merging.
    #
    # Changes to be committed:
    #   modified:   animals.txt
    

    We can remove the “Conflicts: …” lines and commented lines, then save & exit.

    Merge branch 'jungle-animals' into animals
    

Rebasing, Squashing

Rebasing is a great tool to clean up your commits before being pushed to a remote repository. Although it can be done after pushing, it is not recommended unless you know for sure your commits have not been or not being used by any other developers.

We can combine a series of commits into one. This is called “squashing”.

git rebase -i master

pick b11d23a added animals.txt
pick 3fce797 added three water animals to animals.txt
pick 75e509d added three jungle animals to animals.txt
  • I want to combine all three commits into one, so I can squash the two later ones into the first b11d23a:
    pick b11d23a added animals.txt
    squash 3fce797 added three water animals to animals.txt
    squash 75e509d added three jungle animals to animals.txt
    

    Save and exit (Shift + ZZ)
    We see this error message:

    error: could not apply 75e509d... added three jungle animals to animals.txt
    
    When you have resolved this problem, run "git rebase --continue".
    If you prefer to skip this patch, run "git rebase --skip" instead.
    To check out the original branch and stop rebasing, run "git rebase --abort".
    
    Could not apply 75e509dbf9a48559f6ac5d6335554c240c72c45a... added three jungle animals to animals.txt
    

    Git replays each commit one-by-one on top of master and runs into the same conflict we had earlier. So we can fix the conflicts again by removing the conflict markers, then run:
    git add animals.txt

  • We are still running git rebase – since we have fixed the conflict we can continue with:
    git rebase --continue

     # This is a combination of 3 commits.
     # The first commit's message is:
     added animals.txt - three farm animals
    
     # This is the 2nd commit message:
    
     added three water animals to animals.txt
    
     # This is the 3rd commit message:
    
     added three jungle animals to animals.txt
    
     # Please enter the commit message for your changes. Lines starting
     # with '#' will be ignored, and an empty message aborts the commit.
     # rebase in progress; onto d0dd1f6
     # You are currently rebasing branch 'animals' on 'd0dd1f6'.
     #
     # Changes to be committed:
     #   new file:   animals.txt
    
  • We’ll leave the commit message as is with all three commit messages.

  • Save changes Shift + ZZ.
  • detached HEAD d3f629e] added animals.txt
     1 file changed, 9 insertions(+)
     create mode 100644 animals.txt
    Successfully rebased and updated refs/heads/animals.
    
  • Display rebase commit message
  • git log

    commit d3f629e2a2cad4bd61ced309dd15a06737d7ab4d
    Author: Len Isac Seneca <len_isac@hotmail.com>
    Date:   Sat Feb 4 13:39:29 2017 -0500
    
        added animals.txt
    
        added three water animals to animals.txt
    
        added three jungle animals to animals.txt
    

    Three last commits were successfully squashed into one commit.

    Advertisements

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s