What's Git and why should I care?¶
Imagine you're writing a program.. At the beginning, it's small and minimalistic, but it runs without error.
class Calculator: def add(self, a, b): return a + 1
Then you decide you want to add a complicated, experimental feature . Your program starts to grow in size and complexity.
class Calculator: def add(self, a, b): return a + 1 def is_prime(self, x): pass
As you're implementing this new feature, you find and fix a few bugs related to your initial program.
class Calculator: def add(self, a, b): return a + b def is_prime(self, x): # Oof this is hard..
As time goes on, you realize this experimental feature was a mistake . At this point, you want to ditch the experimental feature and revert your code back to how it was originally. But not entirely.. you'd like to keep some of the bug fixes you implemented.
For a large codebase with major changes, doing this without a version control system can be a nightmare. With Git, you can save your code at various "checkpoints", and then revert your code to how it was at any of your saved checkpoints.
You can also branch your project, allowing you to work on multiple features independently of each other and merge those branches such that the code for feature A doesn't overwrite or conflict with the code from feature B.
Don't worry, these things will make more sense once you start practicing!
How it works (the basics)¶
Git lets you track changes to a project (directory) and all its contents by saving the state of your project at various "checkpoints".
Suppose you have a project like this..
my-project/ foo.txt bar.txt
Initializing a Git repo¶
You can set up a Git repository (repo) for your project using the
git init command.
bill@gates:~$ cd path/to/my-project bill@gates:~$ git init Initialized empty Git repository in /path/to/my-project/.git/
This inserts a hidden directory named
.git/ in the root of your project.
my-project/ .git/ foo.txt bar.txt
.git/ is where the saved "checkpoints" of your project live.
Committing your code¶
How do I save a new checkpoint of my project?
Git calls these "checkpoints" commits. To make a new one,
- stage your new and changed files using
- then commit the staged files with
Are you running these commands on your machine?
Don't. Some of these commands won't even work without including additional parameters!
Now's the time to understand the high-level concepts. The time to learn syntax comes when you get to the practice problems.
The commit graph¶
You can visualize each commit as a node in a graph. The first time you commit your code, it's like creating a graph with one node.
With each commit (saved checkpoint), a new node appears connected to the previous node.
Some of you may recognize this as a Directed Acyclic Graph (DAG).
(In this example, each child points to its parent.)
Graphs can even split into multiple branches allowing you to test two or more features from a common starting point.
We'll discuss branches in more detail later.
Your working tree refers to the project you can see and edit on your filesystem. For example, suppose your initial project looks like this
my-project/ foo.txt bar.txt
You commit your files and then you delete
foo.txt<-- delete this abomination! bar.txt
Now your working tree looks like this
foo.txt is not gone forever. It still lives in the commit graph, contained in your first commit! ..but it's
not part of the working tree. In other words, the working tree is all the stuff you can see when you look inside
my-project/ on your computer.
The staging area will make more sense when you solve this problem, but in short, staging is an intermediate place to move your changes before inserting them into the commit graph.
The staging area lets you commit just some of your changes. Without staging, you'd have to commit all of your changes at once!