This blog post is part of the series “Learning web development” – which teaches people who have never programmed how to create web apps with JavaScript.
To download the projects, go to the GitHub repository learning-web-dev-code
and follow the instructions there.
I’m interested in feedback! If there is something you don’t understand, please write a comment at the end of this page.
In this chapter, we learn how to use the version control system Git and a useful companion website, GitHub. Both are important tools when programming in teams but even help programmers who work on their own.
Git is a version control system (a.k.a. source control system). It manages the different versions of the files in a repository (think directory) throughout their history. Git works best with text files such as the web development artifacts .html
, .css
and .js
. But it can also handle binary files.
Use your native package manager to install the git
shell command – e.g.:
Git.Git
git
git
preinstalled, however that tends to be an older version, which is why I recommend to always install it via Homebrew.After installing, run the following command:
git config --global init.defaultBranch main
This is a common setting and disables a tip message that is shown when using git init
(which we’ll use later).
In this section, we explore how we can turn a directory with files into a Git repository and how to use such a repository. You can follow along on your own computer. We’ll use the files when we explore GitHub, so don’t delete them after this section.
We’ll create the following files:
git-demo/
README.md
LICENSE
js/
main.js
README.md
The readme file of a repository describes what’s in it. Its name is often spelled like this: The all-caps are intended to draw attention to it and Markdown has become the most popular format for writing it. Let’s use the following content:
# Git demo
* This Git repository is for practicing Git.
* [More information on Git.](https://git-scm.com/doc)
LICENSE
In the web development community, a lot of code is public. That helps people learn and collaborate. If you publish your code or share it with someone else, you should add a license because it makes it clear what others are allowed to do with your code and what not. Two popular licenses are:
The website “Choose an open source license” can help you find good licenses for your projects.
Once you find a good license for this demo project, copy its text into the plain text file LICENSE
.
js/main.js
Create a file with one or more lines of JavaScript code.
Now it’s time to turn our directory into a Git repository:
% cd git-demo
% git init
Initialized empty Git repository in /tmp/git-demo/.git/
When using Git via a shell, we always invoke the git
command. That command has many subcommands – such as git init
. This command adds the directory git-demo/.git/
which is where Git stores the data it needs to manage this repository.
The subcommand git status
provides us with information about the state of our repository:
% git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
js/
nothing added to commit but untracked files present (use "git add" to track)
Currently, Git does not track any of the files in our directory. Unless we explicitly add a file to the repository, Git ignores it.
Committing (saving) changes to a Git repository happens in two steps:
git add
untracked files and/or changed tracked files.Let’s commit README.md
to our repository. First we stage it:
% git add README.md
% git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
LICENSE
js/
Then we commit the staged changes (option -m
specifies the commit message):
% git commit -m "First commit"
[main (root-commit) ddb66b4] First commit
1 file changed, 4 insertions(+)
create mode 100644 README.md
% git status
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
LICENSE
js/
nothing added to commit but untracked files present (use "git add" to track)
git log
shows the history of our commits to the repository:
% git log
commit ddb66b4383713c4ddedc032a2b75d44c2db0e227 (HEAD -> main)
Author: Axel Rauschmayer <axel@rauschma.de>
Date: Wed Sep 17 16:57:10 2025 +0200
First commit
Notes:
Most repositories contain files that we never want to track. We can tell Git to pretend those don’t exist, by creating the file .gitignore
in the top level of a repository. In JavaScript repositories, this file may look like this:
.DS_Store
node_modules
.DS_Store
is a file created by the macOS Finder that is only need by the local machine. It should never be committed to a repository.node_modules/
directory also usually not committed to repositories: It tends to be large and package-lock.json
records what’s in it so that we can always re-create it precisely.When saving a commit, Git does not store the complete new file, it detects what has changed between the old version and the new version and only stores the difference. That’s why it works so well for text files.
You can explore how computing the differences (diffing) works:
compare-object (get-content one.txt) (get-content two.txt)
diff one.txt two.txt
Git is not just a version control system; it is a distributed version control system. Let’s explore what that means: Each local repository can have zero or more remote repositories that can be stored anywhere: Locally on the machine or remotely, on a server. Each of these remote repositories has a unique name, but it’s most common that repositories have exactly one remote repository with the default name origin
. That default name has the benefit that we don’t need to mention it when we use shell commands.
What is the purpose of a remote repository? We want to keep our local data in sync with the remote data. Two common scenarios are:
A single user that syncs their local repository with a remote repository on a server (e.g. on GitHub, as explained later in this chapter). That means they always have a backup in the cloud.
A team of people that works on a shared repository on a server. Each team member has a local repository whose remote repository is that shared repository. They constantly sync their changes to the shared files.
In the latter scenario, there are no editing conflicts as long as people work on different files. Git handles that case well because it records changes incrementally. Should more than one person change the same file, there may be conflicting edits. Git has strategies for handling those, but that is beyond the scope of this series.
We’ll soon experiment with a remote repository. The following terms are important:
Visual Studio Code has an excellent graphical user interface for Git. Here is how to use it:
My recommendation is to use the shell for creating or cloning repositories and to otherwise use Visual Studio Code as much as possible. Its documentation has more information on its source control functionality.
Exercise: Use Visual Studio Code to commit a file to git-demo/
.
GitHub is a web site that hosts Git repositories and provides various services around those repositories. Per repository, you can determine if it should be private (accessible only to you) or public (readable to everyone). You can also configure which other GitHub users can access a given repository.
Let’s try out GitHub!
github.com
and create an account (unless you already have one).gh
) that helps with using GitHub:
GitHub.cli
gh
gh
to log your whole account into GitHub:gh auth login
Use the default option for each question (detailed instructions).We chose HTTPS to access GitHub, another option is SSH (more information).
What does logging into GitHub give us? It means we can push changes to a GitHub repo without having to log in each time we do so. The user-wide login should work for Visual Studio Code, too (however, I only tested this on macOS).
gh
commands We have already seen one useful gh
command. The only other two I use, are:
gh auth status
gh repo clone <user-name>/<repo-name>
To learn more about the remaining functionality of the GitHub CLI, you can check out the official manual.
github.com
and create a new repository. It should be relatively easy to figure out via the website’s user interface. If not, you can do a web search to find help.gh repo clone
to clone the repository to your drive.git-demo/
into the new directory.github.com
: You should see the file you committed.Single users get automatic backup with infinite undo. That means you never have to worry about accidentally losing code: You can always to back to how things were in the past!
Teams get the aforementioned benefits plus the benefit that Git makes working on a shared set of artifacts much easier.
We have barely scratched the surface of how Git works, but the basics you have learned should get you relatively far. For more information on Git, see:
git-scm.com