DevPath · Learn to code ESPTEN

Git and teamwork

Git in depth: zones, branches, and rewriting

Git's three zones

Git is not "a folder with copies". A change travels through three zones before it is recorded in the project's history:

  1. Working directory: your files exactly as you edit them. Here Git doesn't know about the changes yet.
  2. Staging area (index): the "boarding gate". You choose which changes go into the next commit with git add.
  3. History (local repository): the immutable sequence of commits. Only git commit moves something here.
git status            # what's in each zone?
git add file.js       # working -> staging (you prepare the change)
git add .             # stages EVERYTHING modified
git commit -m "feat: add login"   # staging -> history

Key idea: only git commit writes to the history. git add does not create a save point; it only prepares what will go into the next commit.

A commit is a snapshot identified by a hash (SHA), with author, date, message, and a pointer to its parent commit. That chain of parents is the history.

Branches

A branch is a lightweight pointer to a commit. Creating a branch is almost free and lets you work in parallel without touching main:

git branch                    # list the branches (the current one with *)
git switch -c feature/login   # create and switch to a new branch
git switch main               # go back to main
git log --oneline --graph     # see the tree of commits

HEAD is a pointer to "where you are" (usually the current branch).

Integrating work: merge vs rebase

When your branch and main have advanced separately, you need to integrate. Two strategies:

git merge

Creates a merge commit that joins the two histories. It does not rewrite anything: it preserves the real graph of how the work happened.

git switch main
git merge feature/login   # creates a merge commit joining both branches

git rebase

Reapplies your commits on top of the tip of main, as if you had written them from there. The result is a linear history, with no merge commits.

git switch feature/login
git rebase main           # move your commits on top of main (rewrites them)

When to use each?

Golden rule: never rebase commits that you have already published and others have pulled. Rewriting shared history breaks your teammates' repo. Rebase in private, merge in public.

Resolving conflicts

A conflict happens when merge/rebase can't combine two changes on the same lines. Git marks the file like this:

<<<<<<< HEAD
const greeting = "Hello";
=======
const greeting = "Hi";
>>>>>>> feature/login

You edit the file leaving the final version (deleting the markers), and then:

git add file.js        # mark the conflict as resolved
git commit             # in merge: closes the merge
# or, if you were rebasing:
git rebase --continue
git rebase --abort     # cancel and go back to the previous state

Undoing: revert vs reset

git revert a1b2c3d     # adds a commit that undoes a1b2c3d
git reset --soft HEAD~1    # undoes the last commit, leaves the changes in staging
git reset --mixed HEAD~1   # (default) undoes commit and staging; keeps files
git reset --hard HEAD~1    # undoes EVERYTHING, even your files (dangerous)

Summary: for something already published, revert. For local commits you haven't shared yet, reset.

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 →
Teamwork: PRs, review, and conventions →