How Git works

Git keeps every saved version of a project, and lets several people work on the same files without overwriting each other. This guide builds the idea up one piece at a time, with a small playground in each chapter: click the buttons, watch what changes, and read the commands Git would run.

The blue line down the side is how Git draws history: each dot is a saved version. By the end you'll be reading these diagrams without thinking about it.

What Git is, and what GitHub is

If you've used version history in Fusion, you already know the core idea: every save is a version you can go back to. Git does the same for a whole folder of files (code, post processors, docs, anything text-based) with two differences. You decide when a version is worth keeping, and you write a short note saying what changed.

A folder Git is tracking is called a repository, or repo. Its full history lives inside it, in a hidden folder called .git. Nothing leaves your computer unless you send it somewhere.

GitHub is a separate thing: a website that holds a copy of your repository so other people can get it, add to it and discuss changes.

Git

A program on your computer. Tracks history, makes branches, merges work. Runs offline.

GitHub

A website. Holds the shared copy, and adds pull requests, code review and permissions on top. GitLab and Bitbucket do the same job.

Saving a version takes two steps

Git doesn't save every keystroke. You choose which changes go into the next saved version, called a commit. Your work moves through three places:

Working folder
the files as you see them in your editor.
Staging area
the changes you've picked for the next commit (git add).
History
the commits (git commit). Each one is a snapshot with a message, an author and a short ID.

Why the middle step? You might change three files, but only two belong together. Staging lets you commit those two as one tidy change and leave the third for later.

Playground: save a version

Working folder

Your files as they are now

Staging area

Picked for the next commit

History

Saved commits, newest first

Try this: edit post.cps and notes.txt, stage only post.cps, then commit. Check the status to see what's still waiting.

Branches let you try things safely

A branch is a separate line of work. The main line is usually called main. When you start something new, you make a branch and commit on it as much as you like while main stays untouched. When the work is ready, you merge the branch back in.

Under the hood a branch is just a label pointing at a commit, so making one is instant and free. People make one for every task, however small. HEAD is Git's name for where you are right now: the branch your next commit lands on.

Playground: branch and merge
into the current branch

Try this: make a branch and commit twice. Switch back to main, commit once, then merge the branch in and watch the two lines join. Then make another branch, commit on it, and merge it while main hasn't moved: Git just slides the label forward, called a fast-forward.

Sharing work: push and pull

Everyone on a team has their own complete copy of the repository. GitHub holds the shared copy, which Git calls origin. Three commands move commits between them:

git clone
download a repository the first time.
git push
send your new commits up to GitHub.
git pull
bring down commits other people pushed, and merge them into your copy.

The rule that catches everyone at first: GitHub won't accept your push if it has commits you don't have yet. You pull, Git combines the two histories, then you push.

Playground: you, GitHub and a teammate

Your laptop

GitHub (origin)

The shared copy. Everyone pushes to it and pulls from it.

Ben's laptop

Starting point Your commits Ben's commits Merge commits

Try this: Ben commits and pushes. Then you commit and push. Your push is rejected. Pull, then push again. Finally, have Ben pull so everyone matches.

How a team works together

Most teams follow the same loop, built around pull requests. A pull request (PR) is a page on GitHub that says: here's my branch, please review it and merge it into main. Teammates read the changes there, comment on specific lines and approve.

  1. Get a copy of the project

    Only once per project.

    git clone https://github.com/your-team/project.git
    cd project
  2. Start from the latest main

    So you're building on everyone's newest work.

    git switch main
    git pull
  3. Make a branch for your task

    Name it after the job.

    git switch -c fix-feed-rounding
  4. Work, and commit in small steps

    Small commits with clear messages are easy to review and easy to undo.

    git add post.cps
    git commit -m "Round feedrates to one decimal place"
  5. Push your branch to GitHub

    -u links your branch to the copy on GitHub, so next time plain git push is enough.

    git push -u origin fix-feed-rounding
  6. Open a pull request

    GitHub shows a "Compare & pull request" button after you push. Teammates review. If they ask for changes, commit and push again on the same branch and the PR updates itself.

  7. Merge, then tidy up

    Once it's approved, merge the PR on GitHub. Then bring main up to date locally and delete the finished branch.

    git switch main
    git pull
    git branch -d fix-feed-rounding

The payoff: main always works, because nothing lands there until someone else has looked at it.

When two people change the same line

Usually Git merges on its own. If you edited one part of a file and Ben edited another, both changes are kept. But if you both changed the same lines differently, Git can't know which is right, so it stops and asks you. That's a merge conflict. It's normal and fixable, not a sign you broke anything.

Say you run git merge raise-feed-limit and both branches changed the same line. Git marks the spot in the file:

<<<<<<< HEAD
var maxFeed = 5000;   // your version
=======
var maxFeed = 8000;   // the incoming version
>>>>>>> raise-feed-limit

To resolve it:

  1. Edit the file so it says what it should: one version, the other, or a mix.
  2. Delete the three marker lines.
  3. Stage the file: git add post.cps
  4. Finish the merge: git commit

Conflicts stay small and rare if you pull often, keep branches short-lived, and tell teammates when you're about to rework a shared file.

Cheat sheet

One-time setup

git config --global user.name "Scott Moyse"
git config --global user.email "you@example.com"
git config --global pull.rebase false

Your name and email go on every commit. Use the same email as your GitHub account so commits link to your profile. The last line tells git pull to merge when histories have split, which is what the playground above shows. Newer versions of Git ask you to choose before they'll pull.

Everyday commands

CommandWhat it does
git statusShows your branch and what's changed. Run it constantly.
git add <file>Stages a file. git add . stages everything that changed.
git commit -m "…"Saves the staged changes as a commit.
git diffShows changes you haven't staged yet, line by line.
git log --oneline --graphShows history as a graph, like the playground.
git switch <branch>Moves to another branch.
git switch -c <name>Creates a branch and moves to it.
git merge <branch>Brings another branch's commits into the one you're on.
git clone <url>Downloads a repository for the first time.
git pullGets new commits from GitHub and merges them in.
git pushSends your commits to GitHub.
git restore --staged <file>Unstages a file. Your edits stay.
git restore <file>Throws away uncommitted edits to a file. This can't be undone.

Words you'll hear

Repository
a project folder plus its full history.
Commit
one saved snapshot, with a message, author and ID.
Branch
a movable label marking a line of work.
HEAD
where you are now; your next commit goes here.
Remote, origin
another copy of the repo, usually the one on GitHub.
Pull request
a request on GitHub to review and merge a branch.
Merge conflict
two changes to the same lines that you resolve by hand.
.gitignore
a file listing things Git should never track, like build output or passwords.

When you're unsure what's going on, run git status. It tells you where you are, what's changed, and usually suggests the next command.