We've briefly mentioned Git in previous lessons and you got a chance to install it as part of the previous assignment but now it's time to actually dig in a bit more and understand what Git really is.
Git is an essential professional tool. Github is where just about every developer out there stores his or her portfolio and it's where your next job is likely to host their code as well. Git will be a part of your everyday life as a developer and there's no avoiding it. It can also be incredibly helpful to you as you slowly become aware of its more useful features.
Learning Git can be a bit tough because it's not always conceptually linear, so don't fret if you still feel like you don't have a great handle on it by the end of this mini-course. You really learn Git by needing to use it in a situation and being forced to learn your way out.
Backing up a bit, Git is the version control system used by developers. It means that you can revert to a previous (working) version of the application if you really screwed something up and it means that you have a standardized way of managing a project with contributions from multiple developers. It's even useful if it's just you and you're working on a project on your own with a few half-baked ideas that you're trying to code at the same time but want to keep separated until they've matured sufficiently.
It sort of feels like if you were typing a text document and, every time you saved it, you entered a summary message like "just finished paragraph on how git works". Then, if you realize at the end of the day that all your changes are awful and ruin the flow of the document, you could go back to the last save of yesterday and bring the document back to the way it was.
But wait, you say, "Why not just erase the offending paragraphs and move on?" Here's where the web application stops resembling a high school essay. Changes you make to your web application to build some new feature will be scattered in a dozen different files and will likely involve changing existing code at least as much as it involves actually producing new (and easily deleted) code, so having that ability to just reset the clock to a particular point in the past saves you from having to remember exactly what was changed and what it looked like beforehand.
The power of git goes well beyond this simple example, but it should help you start to see why people use it. In a situation with multiple developers, how do you let them each work on the same code base at the same time? Git keeps track of all the files that have been changed and how and it will help you resolve any situations where two people have changed the same file independently (a "merge conflict").
Your use of Git will, for a long time, likely revolve primarily around the simple act of staging the changes you've made to your local files, committing them to your local Git repository, then pushing them up to Github for safe keeping. Later on, you'll learn how to push that code up to Heroku so it can actually be run on a real web server. You may run into things like merge conflicts now and then if you've messed up your workflow a bit, but 95% of the time it will be incredibly straightforward.
Even strange-sounding activites like forking someone else's repository and cloning it onto your hard drive are all pretty easy to do as well.
Watch the following videos from Github's Youtube Channel:
First, we'll introduce you to version control for developers:
Next, we'll start getting more into a Git workflow:
This video will cover some things you already did to set yours up, so don't worry about doing those again:
$ git init will create a new repository in whatever folder you're currently in. If you've just created a new folder for your project, don't forget to
cd into it or you'll be awfully confused.
$ git status will show you a lot of helpful information to guide you about where you are with Git. It tells you which branch you're currently on, which files have been modified, which files have been modified and are sitting in the staging area waiting to be committed, and which files it's not currently tracking.
You've got three phases a file can go through:
Here's how you do those things from the command line (CLI):
$ git add . will add all files in your current directory. You will need to use
$ git add -A instead if you've got untracked files (usually brand new ones or deleted files). You can also add specific files to your staging area like:
$ git add app/views/lessons/show.html.erb
If you want to remove a file from the staging area, use the following to unstage it:
$ git rm --cached your/file_name
To take everything that's currently in the staging area and actually commit it to your repo, use:
$ git commit -m "some message"
Make a short and sweet sentence about the changes you made, in the present tense. It should be descriptive enough that you'll be able to tell what you were doing on that commit but not more than needed. For example:
$ git commit -m "make navbar responsive"
$ git commit -m "modified three files including application.css.scss to add HTML and CSS media queries at 600px and 400px"
Remember, you'll be looking at these messages later on so you can remember what you were doing. When you do, you'll also easily see which files they got attached to, so don't worry about explaining which files were changed.
You should commit any time you move on to a new feature or set of changes. A good rule of thumb is if you have to use the word "and" in your commit message to describe multiple sets of changes, you probably waited too long.
Commit early and often. This is especially important while you're establishing the habit. It's as important as saving. Forget to do it for a day and you might have 30 files modified in a soupy mess of overlapping changes. Then, when you want to kill only some of those changes, you'll wish you'd remembered. Don't say we didn't warn you.
$ git log will show you the log of your latest git commits. Type
q to exit. Useful when you pick up a project after a few days and can't rememember what happened last.
You'll want to save your code up to Github eventually so other people can use it or just to have a backup, so you first need to create a new repo on Github. It's pretty straightforward -- just follow the directions on their website for doing so.
See the section on remotes below if you're curious what that command is doing :)
Once you're at some sort of stopping point, you will push all your local changes up to the version of your repo that's stored on http://github.com.
$ git push origin master
will push your master branch to Github.
What's a master branch anyway? We'll cover that below.
If you're working with other people or doing work on multiple machines, you'll need to keep your local repo up to date with the remote one sitting on Github. Do this with
$ git pull origin master
Lots of times, you'll want to pull someone else's repo down from Github (or your own repo onto a new machine).
$ git clone https://github.com/your_username_here/your_repo_name_here.git
will create a new folder named after the repo and will download the contents of that repo into that folder. It will also set things up so you can use the
pull commands without any issues.
When you click into a repo on Github, you can actually see a section to the right which contains the URL you need to use to clone it:
Just remember to
cd into the newly created directory!
Also, there are a few different options for which protocol to use --
ssh etc... you can stick with
https if you want, though it will ask you for your username and password every time you pull or push. Set up your SSH keys to start using the ssh protocol. This should have been part of your installations in the previous lesson anyway.
If you want to contribute to someone else's project, you'll first have to copy their Github repo into your own Github repo. This allows you to make changes on your own now-separate repo without messing theirs up and is called "forking". Once that's done, you'll clone your forked version down to your local machine using the
clone command we just covered.
The whole process is done on Github via their website, so see the article they wrote for more details.
A "Remote" just refers to an online repository that you'll be pushing and pulling code from. When you clone a new repo or if you followed the instructions above for setting up a new repo on Github, there's already a remote set up which points to it, called
There's nothing special about the word
origin, it's just conventional to call the online version of your repo
$ git remote will output your remotes. Use the
-v option to show their "verbose" version which contains the URLs. If you've linked your repo to Github, it will display something like:
$ git remote -v origin email@example.com:your_user_name/your_repo_name.git (fetch) origin firstname.lastname@example.org:your_user_name/your_repo_name.git (push)
It's really easy to add or remove remotes, which you might want to do if you're working with someone else. Maybe you've decided to work with their Github repo and want to be able to push and pull changes to and from it -- add a new remote which you can call
upstream for demonstration purposes:
$ git remote add upstream git://github.com/friend_user_name/friend_repo_name.git
Just use the URL you would normally clone from. It's okay if you use the
https: version instead of the
git: version. Now
$ git remote -v shows:
$ git remote -v origin email@example.com:your_user_name/your_repo_name.git (fetch) origin firstname.lastname@example.org:your_user_name/your_repo_name.git (push) upstream email@example.com:friend_user_name/friend_repo_name.git (fetch) upstream firstname.lastname@example.org:friend_user_name/friend_repo_name.git (push)
Deleting is easy too:
$ git remote rm upstream
The first time you'll probably see more remotes than just
origin is when you deploy your repository to the web using Heroku -- in that case, you'll set up a remote called
heroku that you'll push your code up to when you're ready to deploy.
Pull requests are another important feature that makes collaboration using Git easier for developers. Git provides a user-friendly web interface for discussing proposed changes before integrating them into the original repository.
Pull requests let you tell others about changes you've pushed to a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before the changes are merged into the repository.
Branches are another nifty feature of Git. Branching allows you to create multiple versions of your repo. This can be useful in all kinds of scenarios:
fun-front-endwhile the other works on
make-database-faster. You would each merge your changes back into the
masterbranch when you're ready.
As mentioned above, the "home" branch is always called
master. You can change that but... why would you?
Create a new branch with:
$ git checkout -b name_of_a_new_branch
It will take whatever branch you are currently on (which is often
master but maybe you're nesting branches inside each other too) and copies it into the new branch.
When you're done working on your current branch, switch to another using:
$ git checkout name_of_other_branch
You'll see your files change to reflect the state of that branch. It can be cool to watch in your text editor when it updates and reshuffles all those files.
When you're done working on a branch and want to merge it back into your
master branch (or some other branch), you first need to go to the target branch. Merging always happens into wherever you currently are. So first:
$ git checkout master
Then simply use:
$ git merge other_branch_to_merge_in
...and you're good to go.
Fun fact: Merging is also occuring when you do a
$ git pull. Basically, it's treating the code you're bringing down from Github as another branch and then merging it into your current branch. You just don't see that because it's behind the scenes (unless there are conflicts... see below).
If it's just you working on the project, things should go smoothly when you merge one branch into another, case closed.
If you're working with other people or have been simultaneously committing to your
master branch and your
cool_feature branch, then you might have merge conflicts. This isn't anything to be afraid of, it just means that both branches have modified the same file and Git needs you to tell it which changes to keep.
In order to do so, Git stops the merge halfway and waits for your help. If you get some angry-sounding "you have merge conflicts" error message and then hit
git status, you'll see that there are conflicts listed and there are unstaged files. Git is waiting for you to resolve the conflicts and then commit the resulting files in order to complete the merge.
To make your life easier, Git adds what are called "Merge Markers" to your conflicting files so you can easily find the lines that are giving it fits. There will be three of them for each conflict -- one above the lines in question, one below the lines in question, and one in between what Git thinks are the two versions of the lines in question.
Merge markers look something like:
Basically, Git tells you which version of the file corresponds to which area. Your job is to look over the code, decide whether you want one or both sets of changes, then delete the offending markers and save the file.
Once you've removed all the merge conflict markers and saved all the files, you still have to commit all the files to complete the merge. But you already know how to do that, don't you?
Merges won't happen often when you're first starting, so don't worry if your head is spinning from them.
This is a lot to digest, so go re-learn some of the basics by reading over Git Basics from Atlassian.
Git can be tough to wrap your head around and it will take some practice to really get it. For now, just focus on the basic stuff like adding, committing, pushing and pulling. The Resources tab has tons of great resources for learning this stuff (and they often explain things in much better detail and with prettier pictures).
And, as we mentioned at the beginning of the lesson, much of learning this stuff is getting stuck and Googling your way through the answer.
In the next lesson, you'll get a chance to practice more with Git yourself so all this theory can sink in.