Wednesday, November 19, 2014

An Introduction to Branching with Git

This article covers branching in the case that more than one developer will be editing code. This discussion will show how to use the Git Gui to track changes amongst developers and will help to understand how branching works in Git. We start out with following assumptions:
  • Central Repository: "C:\Users\Scott\GitRepos\myrepo.git"
  • (created in the previous post) Ben's Local Repository: "C:\Users\Ben\workspace\myrepo"
  • (created below) Matt's Local Repository: "C:\Users\Matt\workspace\myrepo"
In Git, changes are always done within the current branch and do not affect other branches. Developers can work in their respective branches without breaking the master branch (you can have branches of branches, etc). When they are ready, they can push to the master branch. In this post, we will be using the following three tools below wherever you see "... Run Git Gui, View Git Branches and Check Status ...":
  1. The Git Gui Visualization to see how various git commands work (see Adding Git Version Control to Your Project for more information).
  2. The "git branch -a" command to list all the branches. Green marks the current branch (asterisk). White marks local branches. Red marks central branches.
  3. The "git status" command to see various changes we are making.
Now, to start...
  1. Clone the central repository for a second developer (ie Matt):
    mkdir /c/Users/Matt/workspace/
    cd /c/Users/Matt/workspace/
    git clone /c/Users/Scott/GitRepos/myrepo.git
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • The "git clone" command creates a local repository which is like a snapshot of the central repository.
    • You may make as many clones as you would like, allowing multiple people to push commits to the master branch.
  2. Create a local branch for the first developer (Ben) to work from:
    cd /c/Users/Ben/workspace/myrepo; git checkout master
    git branch dev_Ben
    ... Run Git Gui, View Git Branches and Check Status ...
    git checkout dev_Ben
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • The "git branch dev_Ben" command creates the local dev_Ben branch (green in Git Gui).
    • The "git checkout dev_Ben" command makes dev_Ben the current branch (green/asterisk in Git Branches).
    • The "git branch -d dev_Ben" command can be used to delete the local dev_Ben branch.
  3. Push the new local branch to the central repository:
    cd /c/Users/Ben/workspace/myrepo; git checkout dev_Ben
    git push origin dev_Ben
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • The "git push origin" command pushes the new branch to the central repository to create the central dev_Ben branch (brown in Git Gui).
    • The "git push origin --delete dev_Ben" command can be used to delete the central dev_Ben branch.
  4. Update the second developer's (Matt's) Git Gui visualization:
    cd /c/Users/Matt/workspace/myrepo; git checkout master
    git remote update
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • The "git remote" command updates the view of the central repository.
    • The "git remote" command will not pull in any commits from the central repository and therefore will not change any development being done by Matt. However, Matt can use this to see what has changed in the central repository by Ben.
    • Notice that Matt does not have a local dev_Ben branch since Matt has never checked out the dev_Ben branch. Typically, developers only checkout branches they work in.
  5. Create a local branch for the second developer (Matt) to work from:
    cd /c/Users/Matt/workspace/myrepo; git checkout master
    git branch dev_Matt
    git push origin dev_Matt
    git checkout dev_Matt
    ... Run Git Gui, View Git Branches and Check Status ...
    cd /c/Users/Ben/workspace/myrepo; git checkout dev_Ben
    git remote update
    ... Run Git Gui, View Git Branches and Check Status ...
  6. Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • Notice that Ben has a local master branch (green) and a local dev_Ben branch (green) but does not have a local dev_Matt branch.
    • This is nice because now we can identify whether the Git Gui Visualization belongs to Ben or Matt, respectively.
  7. Have the first developer (Ben) make changes in their branch (dev_Ben):
    cd /c/Users/Ben/workspace/myrepo; git checkout dev_Ben
    touch my-app-readme.txt
    ... Run Git Gui, View Git Branches and Check Status ...
    git add -A
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • The "touch" command just creates a new file.
    • The "git status" command shows the my-app-readme.txt file is untracked before the "git add" command.
    • The "git status" command shows the my-app-readme.txt file is staged for a commit after the "git add" command.
    • The "git reset --hard HEAD" can be used to unstage changes.
    • Notice that Matt cannot see any changes before Ben does a push to the central repository.
  8. Have the first developer (Ben) commit changes to their branch (dev_Ben):
    cd /c/Users/Ben/workspace/myrepo; git checkout dev_Ben
    git commit -m "Added the readme file"
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
  9. Have the first developer (Ben) push changes from their branch (dev_Ben) to the central repository:
    cd /c/Users/Ben/workspace/myrepo; git checkout dev_Ben
    git push origin dev_Ben
    ... Run Git Gui, View Git Branches and Check Status ...
    cd /c/Users/Matt/workspace/myrepo; git checkout dev_Matt
    git remote update
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • After the "git push" command, the central dev_Ben branch (brown in Git Gui) matches the local dev_Ben branch (green in Git Gui).
    • After the "git remote" command, the second developer (Matt) can see any commits made to the central repository.
  10. Pull the changes into the local master branch and then push the changes into the central master branch:
    cd /c/Users/Ben/workspace/myrepo
    git checkout master
    git pull origin dev_Ben
    ... Run Git Gui, View Git Branches and Check Status ...
    git push origin master
    ... Run Git Gui, View Git Branches and Check Status ...
    cd /c/Users/Matt/workspace/myrepo; git checkout dev_Matt
    git remote update
    ... Run Git Gui, View Git Branches and Check Status ...
    Ben's Git Gui Visualization: Matt's Git Gui Visualization:
    • After the "git pull" command, you will see the local master branch (green in Git Gui) matches the central dev_Ben branch (brown in Git Gui).
    • After the "git push" command, you will see the central master branch (brown in Git Gui) matches the local master branch (green in Git Gui).
    • The "git pull origin" command pulls commits from each central branch to the corresponding local branch.
    • The "git pull origin master" command pulls commits from the central master branch to the current local branch.
At this point, Matt will not have Ben's commits from the master branch in any of his local branches. In order to pull Ben's commits, Matt must make the appropriate local branch current via "git checkout" and then run "git pull origin master". If Matt had completed work is his local branch (dev_Matt) and wanted to pull Ben's commits from the master branch, I would suggest pushing that work to his central branch before merging:
cd /c/Users/Matt/workspace/myrepo; git checkout dev_Matt
git add -A
git commit -m "New Changes Before Merging"
git push origin dev_Matt
git pull origin master
After pulling Ben's commits, Matt may have to resolve some conflicts, commit the resolutions and then push them to his central branch:
cd /c/Users/Matt/workspace/myrepo; git checkout dev_Matt
"git commit -a"
... Enter a commit message ...
... Type Esc, Shift+Z, Shift+Z ...
git push origin dev_Matt


This post was reposted from http://scottizu.wordpress.com/2013/08/16/an-introduction-to-branching-with-git/, originally written on August 16th, 2013.

No comments:

Post a Comment