# Git Basics

Git keeps the history of your work. In this course that history does a second job: it is the evidence that the work happened, and when. A semester of real commits is worth more to you than a tidy final state.

We cover this in class early in the term. This page is here for the weeks afterward, when you need to look something up. The slides from that class are at [/topics/git-intro/slides/](/topics/git-intro/slides/).

## Local and remote

Your work exists twice.

- **Local**, the folder on your computer. This is where you edit and where your notebooks run.
- **Remote**, your repository on GitHub. This is the copy I can open, and the one anybody you send the link to sees.

They do not stay in step by themselves. **Commit** records a change locally. **Push** sends your local commits to GitHub. **Pull** brings GitHub's commits down to you. Work that is committed but never pushed is invisible to everybody except you.

## How to commit

Any of these does the same thing. Use whichever you can do without thinking about it.

**GitHub Desktop.** Open your repository, review the changed files on the left, write a message in the bottom box, click Commit to main, then Push origin. This is the path to start with.

**VS Code.** Open the Source Control view from its icon in the Activity Bar on the left, or press `Ctrl+Shift+G` on Windows and on macOS. Hover a file and click the plus to stage it, type a message, click **Commit**, then click **Sync Changes**, which pulls and then pushes.

**The terminal**, from inside your course folder:

```bash
git status                 # what changed
git add .                  # stage everything that changed
git commit -m "Flatten the API response, one row per line item"
git push
```

**Read the file list before every commit.** It should show only files you changed in this project. If it shows files you never made, such as `.vscode`, `.config`, `.copilot` or `AppData`, or hundreds of files at once, your repository is in the wrong folder. Commit nothing and email me. This holds for every repository you make, your website included.

## What goes in your repository

One repository holds everything, because work in a repository can be re-run and a screenshot cannot. Re-running is how anybody checks whether a number is right. What each checkpoint and each assignment asks you to submit is on its Canvas assignment.

Each project needs its own folder inside the `projects` folder, in this same repository. A single history shows when each piece of work happened, and a project that reads a file you already committed for a session should read that file instead of a second copy. The folder for each kind of file is in [Where files go](/guides/python-projects/#where-files-go).

The final project is the one thing that may end up somewhere else. If you want it to stand on its own as something you show people, give it its own repository and link to it from this one's `README.md`. You make that choice in December.

A session notebook becomes your work once you write in it, so it has to go in the `notebooks` folder and be committed. Handbook chapters and anything else you downloaded only to read are not your work. Leave them out, or keep them in a `handbooks/` folder if you like having them nearby. Nothing checks for them.

**Commit what makes the notebook run.** A notebook that runs from what is in the repository is the work. A screenshot of one that ran on your machine at 9 PM is a picture of it. For most sessions that means:

- The marimo notebook you built in class.
- Whatever small input it reads. A CSV under a megabyte has to be in the repository, because a notebook whose data is missing does not run for anybody else.
- The cells where you checked your own numbers. These are part of the work.

## Commit as you go

Commit at the end of each exercise, and commit before you leave the room. Three or four commits across a session cost you nothing and they show where the work happened.

One commit containing everything shows nothing about how you worked. It also costs you the thing git is actually for: when a number changes and you do not know why, a history of small commits lets you find the change that did it. A single commit gives you two states and no path between them.

The timing matters for one more reason. This course is built on the idea that an AI can produce the whole notebook in a minute, so what gets checked is the process that produced it. Commits made in the room, during the session, are the record of that process.

## Writing the message

State what changed and why it changed.

```
Count orders two ways, and note where the two disagree
Fix the join that duplicated every customer row
Add the check that the totals match the source file
```

Compare those to "update", "changes", "wip". In November you will open your own repository looking for the session where the join broke, and one of these two styles will help you.

## Publishing

Some work is published as well as committed. Publishing is a separate step from committing, and work that runs on your machine and was never pushed is not live. [Publishing a Notebook](/guides/publishing-a-notebook/) has the steps. Open the public URL yourself before you call it done.

## What stays out

**Your API key.** It has to stay in marimo's settings and VS Code's model list, both outside the repository, or in a `.env` file that `.gitignore` lists, when a program of your own reads it. [Your AI Tools and Babson Key](/guides/babson-ai-key/) has the details, including what to do if an agent suggests putting the key in a project file.

**Large generated files.** The built DuckDB warehouse is one of these. It comes out of the parquet files, so anybody with your repository can rebuild it, and committing it makes every clone slow. Add these lines to the `.gitignore` in the root folder of your repository:

```
*.duckdb
*.duckdb.wal
```

A `.gitignore` line only affects files Git is not tracking yet, so add it before the first commit that could include them. Git keeps tracking a file you committed before the line existed, and the file stays in your history. If that file held your API key, treat the key as public and ask for a new one, as [Your AI Tools and Babson Key](/guides/babson-ai-key/) describes.

## Starting a session

Pull first, every time, before you touch anything:

```bash
git pull
```

If you edited on a lab machine, or accepted a change on GitHub in the browser, your local copy is behind. Pulling first turns a two-second update into something that is over before it starts. Pulling after you have made changes is where conflicts come from.

## When it goes wrong

**"Nothing to commit."** The files you edited are not inside the repository folder, or you already committed them. `git status` tells you which.

**A push is rejected.** Somebody, usually you on another machine, pushed first. Run `git pull`, deal with whatever it says, and push again.

**A merge conflict.** Git found two versions of the same lines and needs you to choose. The file will contain both, marked with `<<<<<<<` and `>>>>>>>`. Delete the markers and the version you do not want, save, then commit. Notebooks are Python files here, so a conflict in one reads like a conflict in code.

**You committed something huge.** Tell me before you try to undo it. Removing a large file from history is a different operation from deleting the file, and it is easy to make it worse.

## Naming

Name your repository after the course code, lowercase, with no spaces. `OIM 7510 Final!` breaks URLs, breaks some tools on some machines, and is the kind of thing that fails on the one day it matters.
