DevPath · Learn to code ESPTEN

Node.js, npm and testing

Version control with Git

What is Git?

Git is a version control system: a tool that saves the history of changes in your project. It lets you see what changed, when and why, go back to a previous version and collaborate with other people without stepping on each other's work.

Don't confuse Git (the tool) with GitHub (a web service for hosting Git repositories in the cloud and collaborating). Git works perfectly fine without GitHub; GitHub is one of many places where you can publish your repository.

The basic flow: three zones

Git organizes your work into three zones. Understanding this flow is the key to everything:

  1. Working directory: your files as you edit them. This is where you write code.
  2. Staging area (or index): a "waiting room" where you place the changes you want to include in the next snapshot.
  3. Repository: the history of commits. Each commit is a permanent snapshot of the project at a given moment.
  [Working dir]  --git add-->  [Staging]  --git commit-->  [Repository]
   edit here                   prepare                     history

Essential commands

git init                 # creates a Git repository in the current folder
git status               # shows which files changed and their zone
git add file.js          # moves a file to staging
git add .                # moves ALL changes to staging
git commit -m "Message"  # creates a snapshot with the staged changes
git log                  # lists the commit history
git log --oneline        # condensed history (one line per commit)

The commit message describes what and why you changed something. A good message is in the present imperative: "Add validation to the login form".

Branches and merge

A branch is an independent line of development. The main branch is usually called main. Creating a branch lets you work on a new feature without touching the stable code, and then merge it when it's ready.

git branch                    # lists the branches (the current one is marked with *)
git branch new-feature        # creates a new branch
git checkout new-feature      # switches to that branch
git checkout -b new-feature   # creates AND switches to the branch in one step
# ... you make commits on the branch ...
git checkout main             # back to main
git merge new-feature         # merges the branch's changes into main

In modern Git you can also use git switch (switch branches) and git switch -c (create and switch), a clearer alternative to checkout.

.gitignore: what is NOT versioned

Not everything should go into the history. Installed dependencies (node_modules), local configuration files and secrets are not versioned: they take up a lot of space, are regenerated or are private. To exclude them you create a file called .gitignore:

# .gitignore
node_modules/
.env
dist/
*.log

node_modules is rebuilt with npm install from the package.json, so versioning it adds nothing and only creates noise.

Remotes and GitHub

A remote is a copy of the repository hosted somewhere else (for example, GitHub). It lets you make a backup and collaborate.

git remote add origin https://github.com/user/repo.git  # links the remote
git push -u origin main   # pushes your commits to the remote (first time with -u)
git push                  # pushes the following commits
git pull                  # fetches and merges changes from the remote
git clone https://github.com/user/repo.git  # copies an existing repo

The name origin is the convention for the main remote. push sends your work to GitHub; pull brings in what other people have pushed. This is how a team keeps the code in sync.

Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
← Testing and TDDQuality and bundling →