Last time, we went over how to save and upload your work using Git. Today, we’re looking at how to use branching in Git to effectively collaborate with other developers. Git may seem like a lot of effort to save your work, but when you’re working on the same code with other people, figuring out how to reconcile changes and still get a working program can feel impossible. With branching and merging, we can make it a breeze!
So before we do anything else, let’s check where we’re currently at in our repo:
$ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working tree clean
So we’re all set - no changes we left hanging around from last time. Let’s double check that our master branch is up-to-date using
git fetch &
$ git fetch --all Fetching origin $ git pull origin master From https://github.com/burgundyshark/studious-gator * branch master -> FETCH_HEAD Already up-to-date.
Okay, so our repo is clean with no local changes that need to be saved and our remote (Github, in this case) is synced up to our local code. We’re ready to go! Except, right now, if we do work, we’d be doing it on the master branch, which is for everyone. We don’t want to be rude; our teammate’s work is valuable, too. So lets switch to a branch so we don’t disturb anybody:
$ git branch my-first-branch $ git checkout my-first-branch Switched to branch 'my-first-branch' # You do this quickly using the below shortcut: # git checkout -b my-first-branch
So what did we just do here exactly? What the heck is a branch anyways? Let’s visualize this - think of a repo as commits over time, what would that look like?
We can think of each commit as a dot, with the line being the branch. So a branch is a tracked version of your repo that is comprised of an arbitrary number of commits. What you see above is a representation of committing code to the master branch. So lets commit code to our new branch and see what that would look like - so lets make some changes to our codebase! I added some text to my README file, but you could do anything that changes the code. Once you’re done, check to make sure you’re on your branch using
git status, then add and commit your code changes!
$ git status On branch my-first-branch Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a") $ git add -A $ git commit -m "README updates on a new branch" [my-first-branch f92aef3] README updates on a new branch 1 file changed, 1 insertion(+)
Okay, so what does that look like?
Note that our quite linear repo graph now has a curve in it - that represents us branching off from the master branch so we can work independently. In fact, others can commit their work to master while we’re off on our own branch - their work won’t impact ours until we want it to. This is more obvious when there’s commits being made to master, so imagine you’re working with a collaborator that pushes up some work after you start working on your branch. That might look kinda like this:
Our branch looks a lot more like a branch now! Git allows for as many branches as you’d like so you can think of master as the trunk that your work usually branches out from - just like a tree!
Switching between branches isn’t difficult or dangerous, either - using
git checkout you can easily switch between versions of your codebase. Just make sure your files are saved in whatever text editor you’re using - the changes don’t need to be committed, but the files themselves should be saved.
$ git checkout master Your branch is up-to-date with 'origin/master'. $ git checkout my-first-branch Switched to branch 'my-first-branch'
The question now is, how do you get your work back on master so that your collaborator can work with it, too? Well, we’re going to merge our branch back into master!
Before we do anything else, lets check to make sure that there’s no other code that was posted on master before we attempt to merge. If there is new code and we merge our work into the old version of master, we’ll have a messy situation to deal with, so we always want to make absolutely sure that we have the most up-to-date code right before branching and merging. You can do this using
git fetch —all:
$ git fetch --all Fetching origin remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From https://github.com/burgundyshark/studious-gator 0a55ef3..8e09157 master -> origin/master
Look at that! You never know when people might update master, so its always a good idea to check. Now that we know there’s been some changes on master we don’t have, lets get them using
# switches us to the master branch $ git checkout master Switched to branch 'master' Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) # updates your local master branch with new code $ git pull Updating 0a55ef3..8e09157 Fast-forward user.model.js | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 user.model.js
Okay, so we now have an updated master, but how do we get our code on it? We merge our branch back into master using
$ $ git merge my-first-branch Merge made by the 'recursive' strategy. README.md | 1 + 1 file changed, 1 insertion(+)
A lot of the time, you’ll see the phrase
fast-forward in your merge, which means that Git was able to merge your code without adding an extra commit in that merges your branch in. In my case, that didn’t happen, so Git opened my default text editor - when this happens to you (and it will eventually), make sure to note the conditions of the merge in the merge commit message and save & exit - git will wrap up the rest. So what did we just do?
Git allows you to branch out from your master branch, but also gives you the tools to fold your code back into it, allowing for a resolution of any conflicts. So lets push up our new version of master with our branch’s work so our collaborators can make use of the work we’ve done!
$ git status On branch master Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean $ git push origin master Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (5/5), 567 bytes | 567.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0) To https://github.com/burgundyshark/studious-gator.git 8e09157..48700cf master -> master
Now your other collaborators can update their copy of master and merge their branches in, letting everyone on your project work together!
Holy crow, that was a lot - but look at what we did today! We learned about:
- How to keep your repo updated using
- What a branch is and how to visualize Git’s branching system
- How to make your own branch using
- How to switch between branches using
- How to update your master branch while working on your own branch
- How to merge your work into master using
Congrats! You’re officially collaborating with Git now! Next up, we’ll talk about Merges more in-depth, and how to handle them when they go awry.