ap.Abhishek Patel

Search

Search notes, essays, projects, the library and the AI course. Use arrow keys to choose and Enter to open.

Lesson 2 of 5 30 min Beyond the syllabus

Git and GitHub: save points for code

Commit, compare and undo changes with git, experiment on branches, and share and review code on GitHub without ever leaking a secret.

Words in this lessonGit · Repository · Commit · Branch · GitHub · Pull request · Merge conflict · .gitignore
Git
A tool that records save points of your project so you can see changes, undo mistakes and collaborate. Like a bakery's production logbook, with a photo of every recipe card each day and the power to roll back.
Repository
A project folder whose full history is tracked by git. Like a recipe binder that also contains every previous version of every card.
Commit
A saved snapshot of your project in git, with a message saying what changed and why. Like a save point in a video game, made just before the boss fight.
Branch
A separate line of commits where you can try changes without affecting the main version. Like a test kitchen where a new filling is tried out before it goes on the production line.
GitHub
A website that hosts git repositories online for backup, sharing and code review. Like a shared head-office archive where every store's logbook is copied, read and signed off.
Pull request
A request on GitHub to merge one branch into another, where teammates review the changes first. Like submitting a new recipe to the head baker, who tastes it and suggests changes before it goes on the menu.
Merge conflict
What git reports when two branches changed the same lines and it cannot decide which version to keep. Like two bakers editing the same line of a recipe card: someone has to decide which quantity is right.
.gitignore
A file listing the files and folders git should never track, such as .env and .venv. Like a "do not photograph" list for the logbook: the safe's combination never goes in.
On this page
  1. Why "bot_final_WORKING.py" does not work
  2. Following one change through git
  3. Three places your work lives
  4. Branches: a test kitchen for risky ideas
  5. GitHub: sharing, backing up and reviewing
  6. Where it breaks
  7. Try it yourself
  8. Common mistakes
  9. Recap
  10. Go deeper

On Tuesday afternoon, Arjun’s support bot finally behaved. Its drafts were polite, they quoted the real refund policy, and in Priya’s test batch of 50 old emails, not one draft promised a refund. He showed Meera. She smiled for the first time that week.

On Wednesday he “improved” it. A warmer tone here, a shorter instruction there, a new helper function, some tidying. Nine small edits across three files.

On Thursday morning, Priya reruns her 50-email test. Eleven drafts now promise refunds.

“What did you change?” she asks.

Arjun opens his project folder. It contains bot.py, bot_v2.py, bot_final.py, bot_final_WORKING.py and bot_final_WORKING_old.py. He is not sure which one is running. He is not sure which one was Tuesday’s. He spends forty minutes comparing files by eye, gives up, and starts rewriting the prompt from memory.

Meanwhile Priya had emailed him a zip file on Wednesday with her own fix to the escalation rule. He unzipped it over his folder. Her fix overwrote two of his edits, and he has no idea which.

Important

The idea in one sentence: Git records save points (commits) of your whole project, so you can see exactly what changed, when and why, go back to any version that worked, and let several people work on the same code without overwriting each other; GitHub is a website that hosts those git projects so you can share and review them.

Why “bot_final_WORKING.py” does not work

“Have you ever played a long video game?” Priya asks.

“Of course.”

“What do you do before the boss fight?”

“Save.”

“And if the fight goes badly?”

“Load the save. Try again.” Arjun pauses. “I see where this is going.”

“Your files named final and WORKING are you trying to build save points by hand,” Priya says. “Hand-made save points fail in three ways. You forget to make one before the risky change. You cannot tell what is different between two of them without reading both line by line. And when two people make save points separately, nobody can combine them.”

Git is a program that makes save points properly. Each save point is called a commit: a snapshot of every file in your project at one moment, with a short message saying what changed and why, the author’s name, and the time. A project tracked by git is called a repository (or repo). The full list of commits is the project’s history, and you can look at, compare or return to any point in it.

Think of it as the bakery’s production logbook. Every evening the head baker writes what changed in the recipes that day, and pastes in a photo of the recipe cards. If Saturday’s croissants come out flat, you do not guess; you open the logbook to Thursday, when they were perfect, and compare.

Note

Pause and think. Git would have saved Arjun on Thursday only if he had done one thing on Tuesday. What is it?

Show the answer

Made a commit when the bot was working. Git cannot return you to a state it never recorded. The single most valuable git habit is to commit whenever something works, before you start improving it. Tuesday’s working version would then be one command away, and comparing it with Thursday’s broken version would show the guilty line instantly.

Following one change through git

Priya sets up a fresh repository and walks Arjun through the life of a single change, with the real output at each step. You can type along in any empty folder.

Start a repository and make the first save point. The project has a bot.py with the system prompt that worked on Tuesday, and a .gitignore listing files git should never track:

git init
git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore
	bot.py

git init turned the folder into a repository (it creates a hidden .git folder where all history lives). git status is the question you will ask most often: “what is going on?” Right now, git can see two files but is not tracking them.

git add bot.py .gitignore
git commit -m "Add support bot system prompt"
[main (root-commit) 132558e] Add support bot system prompt
 2 files changed, 7 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 bot.py

That is the first save point. 132558e is the start of its commit hash, a unique ID calculated from the contents; yours will be different.

Make a change, and see exactly what it is. Now Arjun repeats Wednesday’s edit: a “warmer” system prompt. Then:

git status --short
git diff
 M bot.py
diff --git a/bot.py b/bot.py
index 5c256c4..ecad306 100644
--- a/bot.py
+++ b/bot.py
@@ -1,4 +1,4 @@
 SYSTEM_PROMPT = (
-    "You are Crumb's support assistant. Draft a reply for a human to review. "
-    "Never promise refunds, credits or discount codes."
+    "You are Crumb's warm, generous support assistant. Draft a reply for a human to review. "
+    "Do whatever it takes to make the customer happy."
)

M means modified. git diff shows the change line by line: lines starting with - were removed, lines starting with + were added. And there it is, in red and green. While making the tone “warmer”, Arjun deleted “Never promise refunds, credits or discount codes” and added “Do whatever it takes to make the customer happy”. To a language model, that is practically an instruction to hand out refunds. Forty minutes of comparing files by eye, answered in one command.

Commit it anyway, to see how going back works.

git commit -am "Make tone warmer"
git log --oneline
87c6515 Make tone warmer
132558e Add support bot system prompt

(-a means “include every tracked file that changed”, a shortcut for git add on each.) git log lists the history, newest first.

Undo the bad change without erasing history.

git revert --no-edit 87c6515

This creates a new commit that exactly reverses commit 87c6515, with the message “Revert ‘Make tone warmer’”. (Without --no-edit, git opens a text editor so you can change the message; if you land in an unfamiliar editor called Vim, type :wq and press Enter to save and leave.) The refund rule is back, and the history honestly records both the mistake and the fix. Priya’s 50-email test goes back to zero refund promises.

Three places your work lives

Arjun asks why there are two steps, add and then commit. Priya draws the answer:

flowchart LR
    W["Working directory: files you edit"] -- "git add" --> S["Staging area: what goes in the next commit"]
    S -- "git commit" --> R["Local repository: history on your laptop"]
    R -- "git push" --> G["GitHub: shared copy"]
    G -- "git pull" --> W
  • The working directory is your files as they are on disk right now, including half-finished edits.
  • The staging area is the tray you load before taking a photo: you choose exactly which changes go into the next commit with git add. This lets you commit the prompt fix on its own, separately from an unrelated half-finished experiment in another file.
  • The local repository is the history on your laptop, written by git commit.
  • GitHub holds a shared copy that others can see, which you update with git push and download from with git pull.

Branches: a test kitchen for risky ideas

Arjun wants to try capping replies at 120 words. It might make them better, or it might break something. Priya suggests he do it on a branch.

“Crumb has a test kitchen,” she says. “When the pastry chef experiments with a new filling, she does not do it on the production line. If the experiment works, it goes into the real menu. If not, nothing was harmed.”

A branch is a separate line of commits that starts from the current one. main is the production line, the version that should always work.

git switch -c shorter-replies
# ...edit bot.py to add MAX_WORDS = 120...
git commit -am "Cap replies at 120 words"
git switch main
Switched to a new branch 'shorter-replies'
[shorter-replies 2dee459] Cap replies at 120 words
 1 file changed, 1 insertion(+)
Switched to branch 'main'

git switch -c creates a branch and moves onto it; git switch main goes back. On main, the 120-word change does not exist. When the experiment proves itself, combine it back in:

git merge shorter-replies

If the experiment fails, leave the branch alone or delete it with git branch -d shorter-replies (git will warn if it has unmerged work). Either way, main was never at risk.

Note

Pause and think. Arjun and Priya both need to change bot.py this week: he is working on reply length, she on the escalation rule. Last week they emailed zip files and her fix silently overwrote his. How do branches change this?

Show the answer

Each works on their own branch, and git combines the work line by line when merging. If they edited different lines, git merges both changes automatically, so nobody’s work is lost. If they edited the same lines, git stops and shows a merge conflict, asking a human to choose, instead of silently letting the last person win. Either way, nothing disappears without someone seeing it. Zip files have no idea who changed which line; git does.

GitHub: sharing, backing up and reviewing

Git works entirely on your laptop. GitHub is a website that hosts git repositories online, which gives you three things: a backup if your laptop dies, a way to share code with your team, and tools to review changes before they reach main. (GitLab and Bitbucket are similar services.)

Connect your project to GitHub. GitHub no longer accepts your account password for git commands, so the easiest route is GitHub’s own command-line tool, gh, which handles sign-in for you. Install it from cli.github.com, then, inside your project:

gh auth login
gh repo create crumb-lab --private --source=. --push

The first command signs you in through your browser. The second creates a private repository on GitHub, links it to your local one (a link called a remote, named origin by default), and pushes your commits. Refresh GitHub in your browser and your files and history are there.

Daily flow. After that, sharing is two commands:

git push   # send my new commits to GitHub
git pull   # bring down commits others have pushed

A teammate gets a full copy of the project, with all its history, using git clone followed by the repository’s address.

Pull requests. At Crumb, nobody pushes straight to main. Arjun pushes his shorter-replies branch to GitHub (git push -u origin shorter-replies; the -u remembers the link for next time) and opens a pull request: a page on GitHub that says “please merge this branch into main”, shows the diff, and lets Priya comment on specific lines. She spots that 120 words cuts off the policy quote on long refund replies, suggests 150, he pushes one more commit, and she approves. Then it is merged.

Pull requests are where much of an AI engineer’s collaboration happens. In Module 18 you will build an AI code reviewer that comments on pull requests automatically, and in Module 14 a coding agent that makes commits of its own.

Where it breaks

Committing a secret. The worst git mistake in AI work. If you commit your .env, the API key is in the history, and deleting the file in a later commit does not remove it: anyone can check out the older commit. If that history is pushed to a public repository, automated bots can find the key within minutes. The fix is not a git command; it is to revoke the key at the provider immediately and create a new one. Prevention is .env in .gitignore before the first commit, and a glance at git status before every git add .. (GitHub also scans for some well-known key formats and may block or warn you, but do not rely on it.)

Committing huge files. Git is built for text files like code. A .venv folder (hundreds of megabytes of installed libraries), a downloaded model (often several gigabytes) or a big dataset will bloat the repository and may be rejected by GitHub, which blocks files over 100 MB. Put them in .gitignore. Libraries are recreated from uv.lock; models are downloaded by code; large files that must be versioned use separate tools such as Git LFS.

Merge conflicts. When two branches change the same lines, git merge stops and marks the file like this:

<<<<<<< HEAD
    "Never promise refunds, credits or discount codes."
=======
    "Never promise refunds or credits. Escalate orders over ₹2,000 to a manager."
>>>>>>> escalation-rule

The part above ======= is your current branch’s version; below it is the incoming branch’s. Edit the file to the version you actually want (here, probably a combination of both), delete the three marker lines, then git add the file and git commit. Conflicts are normal, not errors. VS Code highlights them and offers buttons to accept one side or both.

“Updates were rejected”. If git push refuses because “the remote contains work that you do not have locally”, someone pushed before you. Run git pull to bring their commits down (resolving any conflicts), then push again.

Useless messages. A history full of “fix”, “changes” and “asdf” is a logbook with every page saying “baked stuff”. Write messages that say what and why: “Restore no-refunds rule removed in tone change” will save someone an hour in six months, possibly you.

Try it yourself

In a new practice folder:

  1. Create a repository with a file menu.txt containing three lines: croissant, brownie, plum cake. Commit it.
  2. Create a branch called diwali, add kaju katli and besan ladoo to the menu, and commit.
  3. Switch back to main. Check the menu: the Diwali items should be gone. Then merge diwali into main and check again.
  4. Run git log --oneline and read the story of your menu.
Show the answer
mkdir menu-practice
cd menu-practice
git init
printf "croissant\nbrownie\nplum cake\n" > menu.txt
git add menu.txt
git commit -m "Add base menu"

git switch -c diwali
printf "kaju katli\nbesan ladoo\n" >> menu.txt
git commit -am "Add Diwali sweets"

git switch main
cat menu.txt          # three items: the Diwali sweets are only on the branch
git merge diwali
cat menu.txt          # five items
git log --oneline     # two commits: "Add Diwali sweets" and "Add base menu"

The merge is a “fast-forward”: main had not changed since the branch started, so git simply moved main forward to include the branch’s commit. In PowerShell, create the file in VS Code instead of using printf.

Common mistakes

  • Committing only when “done”. Commit every time something works. Small commits are easy to understand and easy to undo.
  • git add . without looking. Run git status first, every time. It is how you catch .env, a stray model file, or something you did not mean to change.
  • Working directly on main for risky changes. Make a branch. It costs one command and protects the version that works.
  • Treating a conflict as a disaster. It is git refusing to guess. Read both sides, choose, remove the markers, commit.
  • Thinking deleting a file removes it from history. It does not. Leaked secrets must be revoked.

Recap

  • Git records commits: snapshots of your whole project with a message, author and time. A tracked project is a repository.
  • git status and git diff show what changed; git add stages it; git commit saves it; git log shows the history; git revert undoes a commit safely.
  • Branches are test kitchens: experiment without risking main, then merge.
  • GitHub hosts repositories for backup, sharing and review; push, pull and clone move commits around, and pull requests are where changes get reviewed.
  • Never commit secrets or huge files; if a key leaks, revoke it.

By lunch, Arjun has his Tuesday prompt back, Priya’s escalation rule merged on top, and a test run with zero refund promises. He explains it to Meera, who wants to know why Thursday morning was such a mess.

“I had no proper save points,” he says. “Now every time the bot works, I save a snapshot with a note saying what changed. On Thursday, git showed me the exact line I deleted on Wednesday, the ‘never promise refunds’ rule, in one command. And Priya and I can both edit the bot without overwriting each other, because git tracks who changed which line.”

“Like the production logbook,” Meera says.

“Exactly like the logbook. Except it can also undo.”

Priya leans in. “Now that your code is safe, let us look at what it actually does when it calls the model. Your bot sends something across the internet and gets something back. Next lesson: what that something is.”

Go deeper

  • Pro Git: the free, official git book. Chapters 1 to 3 cover everything in this lesson and more.
  • GitHub documentation: repositories, pull requests and authentication.
  • GitHub CLI: the gh tool used above.

Check your understanding

3 quick questions
1. Which command showed Arjun the exact line he had deleted from his system prompt?
2. You committed `.env` with a real API key and pushed it to GitHub. What must you do first?
3. Arjun and Priya change the same line of bot.py on different branches, then merge. What happens?