git is a distributed version control tool
used for tracking changes to files
It's like a filesystem, plus:
brew install git
git is a distributed version control tool that was built by Linus Torvalds in 2005 to help him manage the Linux Kernel project
GitHub is a centralized collaboration website that was started in 2007 by Tom Preston-Werner, Chris Wanstrath and P.J. Hyett, and was acquired by Microsoft in 2018
Does Linus use GitHub? Not much: https://www.wired.com/2012/05/torvalds-github/
Git is a distributed version control system, but for this lesson we will use it locally (i.e. only on a single computer)
a repository (or "repo") contains the version history a collection of files
in git, a repo comprises all files and subdirectories inside a single "root" directory
the command git init
"blesses" the current directory and makes it into a repo
the command git status
describes the state of the current repo
Open up your terminal, cd code
, and type the following commands in order:
command | explanation |
---|---|
mkdir shopping |
makes a directory named shopping (inside the directory named code ) |
cd shopping |
change the current directory to the new shopping directory |
git init |
bless the current directory as a git repo |
git status |
show the state of the current repo |
You should see something like this:
$ git init
Initialized empty Git repository in /Users/alex/code/shopping/.git/
$ git status
On branch master
Initial commit
nothing to commit
If you don't, please ask your neighbors or teachers for help.
git has a two-step process for tracking changes to files.
First, you add the changes to the staging area (also called the cache or the index)
Then, you commit the changes to the history (also called the log)
After a commit, the staging area is cleared, and the cycle continues.
Think of the staging area as a loading dock for a warehouse. Boxes (changes) are put there a few at a time, then moved into the warehouse en masse.
shopping
directory, create a file named groceries.txt
. code .
(that's "code" then a space then a period)Inside groceries.txt
add the following lines:
milk
eggs
chunky monkey ice cream
Go back to the command line and type the following commands:
git status
git add .
(that's "git Space add Space dot Enter")
git status
git status
results. What is different between them? Why?You should now see something like this:
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: groceries.txt
Don't skim past the status message! You won't understand it all yet, but get used to reading over console output and checking for anomalies.
This message is saying that there is one file with staged changes, and it's a file git has never seen before, and its name is groceries.txt
. It's also trying to be helpful by telling you how to unstage this change if you want.
(But you don't want to do this now, so that message isn't actually very helpful, and in fact is adding to the confusing by cluttering the output.)
After adding changes to the staging area, you commit them to history.
Confusingly, the term "commit" is both a noun and a verb -- you run "git commit" on the command line to create a "git commit" in the history :-(
When you create a commit, you always provide a message describing the nature of the changes:
git commit -m 'allow users to change their profile picture'
Commit messages are important. Think of them as journal entries -- without them you will be tracking what you changed, but not why you made the changes.
Now, commit your changes with the following command:
git commit -m "shopping list"
You should see something like this:
[master (root-commit) d8b9565] shopping list
1 file changed, 3 insertions(+)
create mode 100644 groceries.txt
Note that your commit message ("shopping list") is in the top line, and your file name ("groceries.txt") is in the bottom line.
Once again, run git status
, expecting to see:
On branch master
nothing to commit, working tree clean
And to prove that the change actually made it into the history, run git log
.
commit d8b95657eebea7083de1a4fb96ba7fb296637342
Author: Alex Chaffee <achaffee@burlingtoncodeacademy.com>
Date: Fri Sep 7 11:24:33 2018 -0400
shopping list
Again, don't skim past this message. Look for terms you understand. Try to figure out what the program is telling you. Is everything as you would expect? If not, what's different? What don't you understand?
Q: Why does git have a two-step process for tracking changes? Why doesn't git add
just add the changes to the history immediately?
A: ?
Q: Why does git have a two-step process for tracking changes? Why doesn't git add
just add the changes to the history immediately?
A: This lets you tie several related changes together across several files into a single history entry. That single entry is usually related to a coherent functional change, with a descriptive commit message and clear purpose.
Think of "git add" as a rough draft and "git commit" as a published version. "git commit" means "I'm done working for the moment, and I'm ready to share this chunk of work with the team, and discuss it as a single item".
Every commit has a unique id (also known as a hash), which is a long string of letters and numbers.
commit d8b95657eebea7083de1a4fb96ba7fb296637342
Fortunately, git allows you to abbreviate a hash by using its first few digits...
...and in fact, git already showed you an abbreviation when you ran git commit
!
[master (root-commit) d8b9565] shopping list
Look carefully at the digits inside the brackets -- d8b9565
. They are the same digits as the beginning of the full hash above.
The commit id is generated using a cryptographic algorithm known as "SHA-1 hash", which assures that no two commits will ever have the exact same sequence of digits in their ids.
(unless someone tries really hard to force a collision)
Let's pretend that you've gone shopping. You bought ice cream and milk, but the store was out of eggs. And when you got home you noticed you were out of ketchup.
Edit groceries.txt
to contain only the following lines:
eggs
ketchup
Go back to the command line and type the following command:
git status
You should see:
On branch master
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: groceries.txt
no changes added to commit (use "git add" and/or "git commit -a")
Again, git is trying to be helpful here, but mostly just adding parenthetical clutter. Try to figure out what it's actually telling you about the state of your filesystem. (Some answers are on the next slide.)
message | explanation |
---|---|
On branch master |
you are "on" the branch named "master" -- more about branches later |
Changes not staged for commit: |
you have edited some files but haven't added or committed those changes yet |
modified: groceries.txt |
there are some changes inside the file named groceries.txt
|
no changes added to commit |
you haven't staged any of these changes |
Finally, do the two-step:
git add .
git status
git commit -m "oh no, out of condiments"
git status
It is a very good habit to run
git status
incessantly. Like, all the time, between every othergit
command.
Now let's pretend that a few days have passed... (or a few hours...) and you ate all that ice cream and you want more.
But Ben & Jerry's has such weird ice cream names, and you can't remember whether you bought Chunky Monkey or Chubby Hubby or Cherry Garcia!
oh no, it's an ice creaMERGENCY!!!
Fortunately, git is a time machine. You can view any point in history and see the changes made at that point in history.
git log
to show the history listgit show
to show that entryMy commit id is d8b9565
so I would run
git show d8b9565
git show
reveals a lot of information about a single commit, including:
commit d8b95657eebea7083de1a4fb96ba7fb296637342
Author: Alex Chaffee <alex@stinky.com>
Date: Fri Sep 7 11:24:33 2018 -0400
shopping list
diff --git a/groceries.txt b/groceries.txt
new file mode 100644
index 0000000..9f0ab0a
--- /dev/null
+++ b/groceries.txt
@@ -0,0 +1,3 @@
+milk
+eggs
+chunky monkey ice cream
Now we remember ...
Oh, Chunky Monkey, how could I ever forget you?
Diffs (also known as patches) can be difficult to understand at first.
The most important thing is that every line beginning with a +
was added and every line beginning with -
was removed.
Run git show
on your second commit to see something like this:
git show e9c9b25c6
commit e9c9b25c65a83729a90c8740f71dc89432d7b548
Author: Alex Chaffee <alex@stinky.com>
Date: Fri Sep 7 11:53:23 2018 -0400
oh no, out of condiments
diff --git a/groceries.txt b/groceries.txt
index 9f0ab0a..5ae9411 100644
--- a/groceries.txt
+++ b/groceries.txt
@@ -1,3 +1,2 @@
-milk
eggs
-chunky monkey ice cream
+ketchup
It's saying "milk" and "chunky monkey ice cream" were removed, and "ketchup" was added, during that commit.
git push
git pull
shopping
)origin
"):git remote add origin GITURL
git push origin master
Now reload the page and see your changes!
Git does not automatically push and pull changes!
shopping
repo and click on groceries.txt
git pull
git init
initializes a repo inside a directorygit add .
stages all current local changes, including new files and edits inside existing filesgit commit -m "message"
turns the staged changes into a new commit history entrygit show
expands a single commit to show the metadata and changes
git push
sends your change history to a remote repositorygit pull
gets new changes from a remote repository/