
Git is easiest to understand when you stop thinking of it as a backup button.
It records decisions about a project: what changed, when it changed, and which version you want to examine or restore. That makes Git useful even before you collaborate with another developer.
The beginner mistake is to learn commands as isolated actions. Connect each command to a question instead: what changed, what has been saved, what will be shared, and what can be recovered?
The project before Git
Imagine a tiny Python report that counts completed tasks:
tasks = [
{"name": "read the error", "done": True},
{"name": "run the test", "done": False},
]
completed = [task["name"] for task in tasks if task["done"]]
print("Completed:", completed)You run it and see:
Completed: ['read the error']You now have a working starting point. Before changing the program, create a project folder and initialize a repository:
mkdir task-report
cd task-report
git initgit init creates the metadata Git needs for this folder. It does not upload your files, create a GitHub account, or automatically save every future change. It tells Git, “Treat this folder as a repository from now on.”
Place your Python file in the folder, then ask Git what it sees:
git statusA new file is usually shown as untracked. That means the file exists in your working folder, but it is not yet part of a commit.
Git has three places to keep in mind
Beginners often imagine Git as a button that copies a folder somewhere else. A more useful mental model has three layers:
- Working tree: the files you are currently editing.
- Staging area: the exact changes you are preparing for the next snapshot.
- Repository history: the commits Git has already recorded.
Move the first file into the staging area:
git add task_report.py
git statusThen create a commit:
git commit -m "Create first task report"A commit records a snapshot of the staged content, along with metadata and a message. The official Git documentation for git commit describes the command as recording changes to the repository. The staging step matters because it lets you choose which changes belong in that snapshot.
The commit message should describe the result, not your mood. “Fix stuff” gives a future reader little information. “Create first task report” explains what changed at this point in the project.
The change that breaks the evening
Now you decide to make the report more useful by printing open tasks too. You edit the list comprehension but accidentally use the wrong dictionary key:
open_tasks = [task["complete"] for task in tasks if not task["done"]]When you run the file, Python raises a KeyError. You could stare at the screen, ask an assistant to rewrite the entire script, or investigate the exact change first.
Start with:
git status
git diffgit status tells you which files are changed. git diff shows the unstaged difference between your working file and the version Git knows from the relevant index state. The official Git documentation for git diff explains how the command compares sources and helps you inspect what changed.
The important lesson is not only the command. It is the order of operations: reproduce the problem, inspect the change, then decide whether to edit, stage, or restore. Git gives you evidence before you make another guess.
Why staging is more than an extra command
Suppose you fixed the key but also added a temporary print statement while investigating. You may not want both changes in the same commit.
git diff
# inspect the unstaged changes
git add task_report.py
git diff --stagedThe first diff shows changes not yet staged. The second shows what the next commit would contain. This is your review window.
For a beginner building a portfolio project, this habit is valuable because it creates a natural explanation: “I changed the report, reviewed the staged diff, and then recorded the working result.” You are practicing a small version of the review discipline used when several people need to understand a change.
Once the code is correct, commit it:
git commit -m "Report open tasks"What a commit can and cannot recover
List the history:
git log --onelineYou may see something like:
8a2c1f4 Report open tasks
3f9b2a1 Create first task reportThe short identifiers are references to commits. Your identifiers will be different.
Git can restore content that was recorded in a commit. It cannot magically recover a change that was never saved or committed. If you wrote a new paragraph and deleted it before creating any snapshot, Git may have no copy of that paragraph.
This distinction prevents a dangerous assumption: Git is not a replacement for backups, and a local repository is not automatically a remote backup. Commit meaningful checkpoints, and push important work to a remote repository only after checking what you are sharing.
Recover a file without erasing everything
Suppose you make another experiment in task_report.py, decide it is not useful, and want to return the file to the last committed version. First inspect it:
git diffIf you are certain you want to discard the unstaged changes in that file, use:
git restore task_report.pyThe official Git documentation explains that git restore restores paths in the working tree and can also restore the index when used with --staged. This command can discard work, so do not run it merely because a tutorial includes it. Read git diff first and make sure the change is truly disposable.
If the unwanted change is already staged, inspect it:
git diff --stagedThen remove it from the staging area without necessarily discarding the working-file edit:
git restore --staged task_report.pyAfter that, the change is back in the working tree where you can edit it, keep it, or discard it deliberately. Separating “unstage” from “delete” is one of the safest distinctions to learn early.
A branch is a safe experiment, not a second copy you fear
Your report works, but you want to try a different output format. You do not want to disturb the version you could show in class or include in a portfolio. Create a branch:
git switch -c table-outputNow make the experiment and commit it if it becomes useful:
git add task_report.py
git commit -m "Try table-style output"Return to the main branch:
git switch mainIf your repository uses another default branch name, use the name shown by git branch --show-current. Switching branches changes the files in your working directory to match the selected branch. Save or commit work before switching so Git does not have to guess what should happen to uncommitted changes.
The Git Book explains that a branch is a lightweight movable pointer to a commit. You can think of it as a labeled line of development. It lets you try a change without mixing the experiment into the branch you want to keep stable.
The difference between Git and GitHub
Git is the version-control program running on your computer. GitHub is a service where repositories can be stored and shared online. You can use Git without GitHub, and a GitHub repository still uses Git concepts such as commits, branches, remotes, and pull requests.
The official GitHub documentation describes a repository as a place for code, files, and revision history. It also distinguishes branches, clones, remotes, and pull requests.
For a beginner preparing a first portfolio project, do not publish a repository simply to have a green activity square. Check the repository first:
- Does the README explain what the project does?
- Does the repository contain passwords, API keys, private data, or employer code?
- Can someone run the project from the instructions?
- Do the commits show understandable steps?
- Is the repository visibility appropriate?
GitHub’s documentation warns that public repositories expose code to everyone on the internet and discusses security features such as secret scanning and push protection. A public portfolio can be useful, but visibility is a security decision, not just a career decision.
A realistic first-project workflow
Here is a small routine you can use while working on a project after class or during a study session:
- Run the program and reproduce the current behavior.
- Make one focused change.
- Run the program again and observe the result.
- Use
git diffto inspect what changed. - Stage only the changes that belong together.
- Use
git diff --stagedto review the proposed snapshot. - Commit with a message that describes the result.
- Write a short note if the decision is not obvious.
This routine is intentionally slower than editing ten files and committing “updates.” It gives you small recovery points and makes your learning visible. If something breaks, you can ask, “Which change introduced this behavior?” instead of “Which version of the whole folder should I download again?”
What to say when someone asks why you use Git
A beginner-friendly answer is not “Git is required for developers.” Try:
“I use Git to record meaningful versions of my project, inspect changes before committing them, and experiment on a branch without losing the stable version.”
That answer connects commands to decisions. It also gives you something concrete to demonstrate in a classroom discussion, a code review, or an entry-level portfolio conversation.
The Bureau of Labor Statistics describes developers as designing applications and QA analysts and testers as identifying problems and reporting defects. Git does not qualify you for a job by itself. It is one tool that helps you show how you manage changes, investigate failures, and communicate what happened.
Before you type a recovery command
Commands that restore or overwrite files deserve a pause. Ask yourself:
- Is the change committed, staged, or only in the working tree?
- Have I read the relevant diff?
- Do I want to remove the change or only remove it from staging?
- Could this folder contain work I have not copied elsewhere?
- Am I in the repository I think I am in?
When you are unsure, make a backup copy of the file before experimenting. A command that is technically correct can still be the wrong action if you have not decided which work to preserve.
Git becomes useful when the history tells a story
At the end of this small project, the history might tell a simple story:
git log --oneline --decorate --graph --allIt can show the first report, the open-task change, and the table-output experiment on its own branch. That history is not valuable because it is long. It is valuable because another person can understand what you tried, what you kept, and where a change was isolated.
Start with a local repository. Make a small commit. Read a diff. Restore only when you understand what will be discarded. Create a branch when you need a safe experiment. Push to GitHub only after checking the repository’s contents and visibility..
Before learning another Git command, practice answering the four questions behind the workflow: what changed, what is staged, what is committed, and what is shared. If those distinctions are clear, Git stops feeling like a collection of mysterious verbs and becomes a readable history of decisions.

Alex Carter is the editorial name behind Vandutz Academy, a programming blog for beginners. Alex reviews and tests the examples and explanations published on the site, with a focus on making Python, JavaScript, web development, and developer tools easier to understand.