Git Tutorial
Mac/Linux Setup
Installing Git
Here is a general installation on Mac/Linux. If you are using Windows, then enjoy yourself.
Git is actually installed on MacOS, but we’ll be reinstalling it so that we’ll have the newest version:
- go to Git
- download the software for Mac
- install Git choosing all of the default options
First Time Git Configuration
Before you can start using Git, you need to configure it. Run each of the following lines on the command line to make sure everything is set up.
# sets up Git with your name
git config --global user.name "<Your-Full-Name>"
# sets up Git with your email
git config --global user.email "<your-email-address>"
# makes sure that Git output is colored
git config --global color.ui auto
# displays the original state in a conflict
git config --global merge.conflictstyle diff3
git config --list
Git & Code Editor
The last step of configuration is to get Git working with your code editor. Below are three of the most popular code editors.
Atom Editor Setup
git config --global core.editor "atom --wait"
Sublime Text Setup
git config --global core.editor "'/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl' -n -w"
VSCode Setup
git config --global core.editor "code --wait"
Create a Git Repo
Create a Repo from Scratch
mkdir -p git-practice/new-git-project && cd $_
Use git init
to initialize a empty new empty Git repository.
.Git Directory Contents
Here’s a brief synopsis on each of the items in the .git directory:
- config file - where all project specific configuration settings are stored.
- description file - this file is only used by the GitWeb program, so we can ignore it
- hooks directory - this is where we could place client-side or server-side scripts that we can use to hook into Git’s different lifecycle events
- info directory - contains the global excludes file
- objects directory - this directory will store all of the commits we make
- refs directory - this directory holds pointers to commits (basically the “branches” and “tags”)
Clone An Existing Repo
Clone from URL
git clone https://github.com/udacity/course-git-blog-project
Clone with rename
git clone https://github.com/udacity/course-git-blog-project blog-project
Determine A Repo’s Status
git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
- On branch master – this tells us that Git is on the master branch.
- Your branch is up-to-date with ‘origin/master’. – Because git clone was used to copy this repository from another computer, this is telling us if our project is in sync with the one we copied from. We won’t be dealing with the project on the other computer, so this line can be ignored.
- nothing to commit, working directory clean – this is saying that there are no pending changes.
Git Log Command
Use Git Log
git log
By default, this command displays:
- the SHA
- the author
- the date
- the message
It will display the log in less
mode:
to scroll down, press
- j or ↓ to move down one line at a time
- d to move by half the page screen
- f to move by a whole page screen
to scroll up, press
- k or ↑ to move up one line at a time
- u to move by half the page screen
- b to move by a whole page screen
press q to quit out of the log (returns to the regular command prompt)
- Use git log to find the commit that has a SHA that starts with f9720a. Who made the commit?
- Use git log to find the commit with the SHA that starts with 8aa6668. What is the message for that commit?
- Use git log to find the commit with the SHA that starts with f9720a9. When was that commit made?
- Use git log to find the commit that has the message Set article timestamp color. Which commit belongs to that SHA? Provide the first 7 characters of the SHA.
Change Git Log Displays
- the SHA - git log will display the complete SHA for every single commit. Each SHA is unique, so we don’t really need to see the entire SHA. We could get by perfectly fine with knowing just the first 6-8 characters. Wouldn’t it be great if we could save some space and show just the first 5 or so characters of the SHA?
- the author - the git log output displays the commit author for every single commit! It could be different for other repositories that have multiple people collaborating together, but for this one, there’s only one person making all of the commits, so the commit author will be identical for all of them. Do we need to see the author for each one? What if we wanted to hide that information?
- the date - By default, git log will display the date for each commit. But do we really care about the commit’s date? Knowing the date might be important occasionally, but typically knowing the date isn’t vitally important and can be ignored in a lot of cases. Is there a way we could hide that to save space?
- the commit message - this is one of the most important parts of a commit message…we usually always want to see this
What could we do here to not waste a lot of space and make the output smaller? We can use a flag.
The git log command has a flag that can be used to alter how it displays the repository’s information. That flag is –oneline:
git log --oneline
Viewing Modified Files
The git log command has a flag that can be used to display the files that have been changed in the commit, as well as the number of lines that have been added or deleted. The flag is –stat (“stat” is short for “statistics”):
git log --stat
- how many files were modified in the commit with the SHA 6f04ddd?
- How many files were modified in the commit with the SHA 8d3ea36?
- How many lines of code were deleted in index.html in the commit with the SHA 8d3ea36?
Viewing File Changes
The git log command has a flag that can be used to display the actual changes made to a file. The flag is –patch which can be shortened to just -p:
This command adds the following to the default output:
- displays the files that have been modified
- displays the location of the lines that have been added/removed
- displays the actual changes that have been made
git log -p
- look at the commit with the SHA 50d835d. What line number in app.css should you start looking at to see what has been changed?
- Using git log and any of its flags, what code was added in by commit 4a60beb?
- git log –stat and git log -p are both really helpful commands. Wouldn’t it be great if we could have both of their output at the same time?
- What does the -w flag do to the patch information?
Viewing A Specific Commit
You must be tired with the scrolling of the previous practices, how about supply the SHA of a commit as the final argument for all of these commands?
git log -p fdf5493
It still show other commits when scrolling.
The other command that shows a specific commit is git show:
git show fdf5493
The git show command will show only one commit.
By default, git show displays:
- the commit
- the author
- the date
- the commit message
- the patch information
- How many rulesets are added to the CSS by commit 8d3ea36?
- There’s a commit with the message “Convert social links from text to images”. How many files were changed by this commit?
- Look at commit fdf5493. What’s the first HTML heading element that’s added by this commit?
Add Commits
Git Add
Make a new-git-project
directory, and cd
into it, then git init
it.
First, create a file named index.html
, and fill it with some starter code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blog Project</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<script src="js/app.js"></script>
</body>
</html>
Things to note, the code references a CSS file and a JavaScript file.
Now create the CSS and JavaScript files. You can leave both of these files empty. We’ll add content to them in a bit.
We just made a number of changes to the repository by adding files and content. It’s time to do a quick check-in with Git:
git status
The Git noticed that there are some changes in the repository, so let’s stage those files.
$ git add index.html css/app.css js/app.js
# Same as
$ git add .
When you use:
git status
You can find that:
use "git rm --cached <file>..." to unstage
Git Commit
# check your default commit editor
git config --global core.editor
git commit
# Or just with -m flag
git commit -m "Initial commit"
Now add this just inside the body tag in index.html:
<header>
<h1>Expedition</h1>
</header>
git status
git add .
git commit
How to write the commit message
The goal is that each commit has a single focus. Each commit should record a single-unit change. Now this can be a bit subjective (which is totally fine), but each commit should make a change to just one aspect of the project.
Now this isn’t limiting the number of lines of code that are added/removed or the number of files that are added/removed/modified. Let’s say you want to change your sidebar to add a new image. You’ll probably:
- add a new image to the project files
- alter the HTML
- add/modify CSS to incorporate the new image
A commit that records all of these changes would be totally fine!
Conversely, a commit shouldn’t include unrelated changes - changes to the sidebar and rewording content in the footer. These two aren’t related to each other and shouldn’t be included in the same commit. Work on one change first, commit that, and then change the second one. That way, if it turns out that one change had a bug and you have to undo it, you don’t have to undo the other change too.
Do
- do keep the message short (less than 60-ish characters)
- do explain what the commit does (not how or why!)
Do not
- do not explain why the changes are made (more on this below)
- do not explain how the changes are made (that’s what git log -p is for!)
- do not use the word “and”. If you have to use “and”, your commit message is probably doing too many changes - break the changes into separate commits. e.g. “make the background color pink and increase the size of the sidebar” The best way that I’ve found to come up with a commit message is to finish this phrase, “This commit will…”. However, you finish that phrase, use that as your commit message.
Git Diff
The git diff
command can be used to see changes that have been made but haven’t been committed, yet.
Having Git Ignore Files
The .gitignore
file is used to tell Git about the files that Git should not track. This file should be placed in the same directory that the .git
directory is in.
gitignore.io is a good tool to generate .gitignore
file.
Tagging, Branching, amd Merging
Tagging
The command we’ll be using to interact with the repository’s tags is the git tag command:
git tag -a v1.0
This will open your code editor and wait for you to supply a message for the tag. How about the message "Ready for content"?
CAREFUL: In the command above (git tag -a v1.0) the -a flag is used. This flag tells Git to create an annotated flag. If you don't provide the flag (i.e. git tag v1.0) then it'll create what's called a lightweight tag.
Annotated tags are recommended because they include a lot of extra information such as:
the person who made the tag
the date the tag was made
a message for the tag
Because of this, you should always use annotated tags.
After saving and quitting the editor, nothing is displayed on the command line. So how do we know that a tag was actually added to the project? If you type out just git tag, it will display all tags that are in the repository.
Branching
The git branch command is used to interact with Git’s branches:
git branch
It can be used to:
- list all branch names in the repository
- create new branches
- delete branches
Create A Branch
To create a branch, all you have to do is use git branch and provide it the name of the branch you want it to create. So if you want a branch called “sidebar”, you’d run this command:
git branch sidebar
The git checkout Command
Remember that when a commit is made that it will be added to the current branch. So even though we created the new sidebar, no new commits will be added to it since we haven’t switched to it, yet. If we made a commit right now, that commit would be added to the master branch, not the sidebar branch. We’ve already seen this in the demo, but to switch between branches, we need to use Git’s checkout command.
git checkout sidebar
It’s important to understand how this command works. Running this command will:
- remove all files and directories from the Working Directory that Git is tracking (files that Git tracks are stored in the repository, so nothing is lost)
- go into the repository and pull out all of the files and directories of the commit that the branch points to
Branches In The Log
The branch information in the command prompt is helpful, but the clearest way to see it is by looking at the output of git log. But just like we had to use the –decorate flag to display Git tags, we need it to display branches.
git log --oneline --decorate
Delete A Branch
A branch is used to do development or make a fix to the project that won’t affect the project (since the changes are made on a branch). Once you make the change on the branch, you can combine that branch into the master branch (this “combining of branches” is called “merging” and we’ll look at it shortly).
Now after a branch’s changes have been merged, you probably won’t need the branch anymore. If you want to delete the branch, you’d use the -d flag. The command below includes the -d flag which tells Git to delete the provided branch (in this case, the “sidebar” branch).
git branch -d sidebar
One thing to note is that you can’t delete a branch that you’re currently on. So to delete the sidebar branch, you’d have to switch to either the master branch or create and switch to a new branch.
Deleting something can be quite nerve-wracking. Don’t worry, though. Git won’t let you delete a branch if it has commits on it that aren’t on any other branch (meaning the commits are unique to the branch that’s about to be deleted). If you created the sidebar branch, added commits to it, and then tried to delete it with the git branch -d sidebar, Git wouldn’t let you delete the branch because you can’t delete a branch that you’re currently on. If you switched to the master branch and tried to delete the sidebar branch, Git also wouldn’t let you do that because those new commits on the sidebar branch would be lost! To force deletion, you need to use a capital D flag - git branch -D sidebar.
Git Branch Recap
To recap, the git branch command is used to manage branches in Git:
# to list all branches
git branch
# to create a new "footer-fix" branch
git branch footer-fix
# to delete the "footer-fix" branch
git branch -d footer-fix
Branching Effectively
First, make sure we’re on the same page and have the same starter code. We’re going to be working in the new-git-project project. The project has the following files:
- index.html
- css/app.css (empty)
- js/app.js (empty)
The CSS and JavaScript files are empty. Make sure the index file has the following content:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blog Project</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<header>
<h1>Expedition</h1>
</header>
<div class="container">
<main>
</main>
</div>
<footer>
Made with ♥ @ Git Practice
</footer>
<script src="js/app.js"></script>
</body>
</html>
The Game Plan
Right now we have all of our code on the master branch (which is the default branch). We’re about to work with branches, by:
- adding content to them
- creating new branches
- switching back and forth between them
Let’s use branches to make the following changes:
- on the master branch - add a default color to the page
- create a sidebar branch - create a sidebar for the page
- on the master branch - change the heading of the page
- on the sidebar branch - add more content to the sidebar
- create a footer branch - add social links to the footer
Change 1 - Add Page Color
Make sure you’re on the master branch and add the following content to css/app.css:
body {
background-color: #00cae4;
}
Save the file. Then add the file to the staging index and commit it to the repository.
Change 2 - Add Sidebar
Let’s add a sidebar to the page. But let’s say that we’re not really sure if we like the new background color. So we’ll place the sidebar branch on the commit before the one that sets the page’s color. Your SHAs will be different, but, for me, the commit that’s before the one that adds the color has a SHA of 5bfe5e7. So adding the branch to that commit would look like:
git branch sidebar 5bfe5e7
Now use the git checkout command to switch to the new sidebar branch.
Running a git log –oneline –decorate shows sidebar.
Did you notice that the master branch does not display in the output? Where did it go!?! Is it lost? Don’t worry, it’s still there, we’ll see how to get it to display in just a second.
But first, in your code editor, switch to the app.css file. Notice that it does not have the CSS we previously entered! Because of this, if you load the project up in the browser, the page won’t have a colored background. This makes sense since the CSS file is empty, but do you know why?
Create a sidebar by adding the following
<div class="container">
<main>
</main>
</div>
<!-- start of new content -->
<aside>
<h2>About Me</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos, debitis earum molestias veniam suscipit aliquam totam exercitationem tempore neque vitae. Minima, corporis pariatur facere at quo porro beatae similique! Odit.</p>
</aside>
<!-- end of new content -->
<footer>
Made with ♥ @ Git Practice
</footer>
I added my