Getting to Know Git

We'll show you all you need to know to get started using a Git workflow.

Scroll down...

Content

Resources

Comments

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.

Why Git is Useful

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 Path to Git

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.

The Overview of Git

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:

Basic Concepts and Commands

Firing up a New Repo

$ 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.

Checking the Status of Your Repo

$ 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.

git status output

Staging and Committing Changes

You've got three phases a file can go through:

  1. The normal workspace contains all your files. You can do whatever you want with them and Git won't be affected. Make changes to files, delete them, add new ones...
  2. Add a file to the "Staging Area" when you're ready to commit your changes to the repo. The staging area is important (versus just committing in one step) because you often want to only add specific files at a time to a given commit.
  3. Commit to send all changes in the staging area into your repo in one batch. You add a message to yourself so you can later see what the commit contains.

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"

What Should My Commit Message Say?

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"

NOT

$ 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.

When Should I Commit?

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.

Checking Your Commit History

$ 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.

Creating a New Repo on Github

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 :)

Pushing up to Github

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.

Pulling From Github

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

Intermediate Concepts and Commands

Cloning an Existing Repo from Github

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 push and 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:

Git clone URL

Just remember to cd into the newly created directory!

Also, there are a few different options for which protocol to use -- https, 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.

Forking a Repo on Github

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.

Fork a Repo Button

The whole process is done on Github via their website, so see the article they wrote for more details.

Checking Your Remotes

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 origin.

There's nothing special about the word origin, it's just conventional to call the online version of your repo origin.

$ 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  git@github.com:your_user_name/your_repo_name.git (fetch)
origin  git@github.com:your_user_name/your_repo_name.git (push)

Adding or Removing Remotes

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  git@github.com:your_user_name/your_repo_name.git (fetch)
origin  git@github.com:your_user_name/your_repo_name.git (push)
upstream  git@github.com:friend_user_name/friend_repo_name.git (fetch)
upstream  git@github.com: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

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.

From Github:

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.

When to Use Branches

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:

  • You're working on an experimental new feature and want to keep its development on a completely different track from your main code base. You will be able to merge it in later when you're ready. You might call that new branch killer-feature-1234.
  • You want to keep the version of your repository which contains all the in-progress changes separate from the version which is ready to deploy. You might call that in-progress branch develop.
  • You want to collaborate with another developer and both work on separate features at once. One of you might work on fun-front-end while the other works on make-database-faster. You would each merge your changes back into the master branch when you're ready.

As mentioned above, the "home" branch is always called master. You can change that but... why would you?

Creating a Branch

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.

Jumping to a Different 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.

Merging Branches

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).

Merge Conflicts

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.

Merge Markers

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:

Git merge conflict markers

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.

Resolving the Merge

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.

Still Shaky?

This is a lot to digest, so go re-learn some of the basics by reading over Git Basics from Atlassian.

Closing Thoughts

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.



Sign up to track your progress for free

There are ( ) additional resources for this lesson. Check them out!

Sorry, comments aren't active just yet!

Next Lesson: Git Calisthenics