Version control with Git

Git keeps the history of a project: every saved version of every file, who changed it, and why. You can see what changed, go back to a version that worked, and work with other people without overwriting each other. Almost every software project uses it.

Three places

  • the working folder: the files you edit;
  • the staging area: the changes you have chosen for the next snapshot;
  • the repository: the saved snapshots, called commits, kept in a hidden .git folder.

Your first commits

git init                        # start a repository in this folder
git status                      # what has changed? (use it all the time)
git add main.c stack.c stack.h  # put these changes in the staging area
git commit -m "Add a stack"     # save a snapshot with a message
git log --oneline               # list the commits, newest first

Before your first commit, tell Git who you are: git config --global user.name "Your Name" and the same with user.email.

Seeing what changed

#include <stdio.h>
#include <string.h>

int main(void) {
    const char *before[] = {"total = 0", "for each mark", "total += mark", "print total / n"};
    const char *after[] = {"total = 0", "for each mark", "total += mark", "print (double) total / n"};
    int n = 4;
    for (int i = 0; i < n; i++) {
        if (strcmp(before[i], after[i]) == 0) {
            printf("  %s\n", before[i]);
        } else {
            printf("- %s\n", before[i]);
            printf("+ %s\n", after[i]);
        }
    }
    return 0;
}
Open in compiler

git diff shows the changes you have not staged yet, line by line: a line starting with - was removed, + was added, and the others are unchanged context. This program compares two versions of a short file the same simple way. (Git's real diff also finds inserted and deleted lines, not only changed ones.)

CommandWhat it does
git diffchanges not staged yet
git diff --stagedchanges that will go into the next commit
git restore main.cthrow away your changes to main.c
git show abc123what one commit changed

Branches

A branch is a separate line of work. Make one for each feature or fix, so main always works:

git switch -c fix-average   # make a branch and move to it
# ... edit, add, commit ...
git switch main             # back to main
git merge fix-average       # bring the fix into main

If both branches changed the same lines, Git stops with a merge conflict and marks the file with <<<<<<<, ======= and >>>>>>>. Edit the file to the version you want, remove the markers, then git add and git commit.

Sharing with GitHub

GitHub (or GitLab) keeps a copy of your repository online. git clone URL copies a repository to your computer, git push sends your commits up, and git pull brings other people's commits down.

Good habits. Commit small steps, each with a message saying what and why: "Fix integer division in average", not "update". Add a .gitignore file listing what should not be saved, such as *.o, app and a.out. Never commit passwords or keys: once pushed, assume someone has seen them.

Quick check

1. What does git add do?
2. In git diff, what does a line starting with + mean?
3. Why work on a branch?

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.