1.4.11 · D5Python & Scientific Computing

Question bank — Git version control basics

1,805 words8 min readBack to topic

Before we start, the handful of words we lean on constantly, in plain language:

The picture below is the map to keep in your head — refer back to it whenever a card mentions one of the three areas:

Figure — Git version control basics
Figure — Git version control basics

True or false — justify

Git stores a full separate copy of every file in every commit
False in spirit — Git conceptually stores snapshots, but unchanged files are stored once and referenced by later commits, so identical content is never duplicated on disk.
A branch is a heavy copy of your whole project
False. A branch is just a tiny label — a file holding one commit's 40-character hash plus a newline (about 41 bytes on disk). Creating one copies no project files, which is why branching is nearly free.
Running git add permanently saves your changes
False. git add only moves changes into the staging area; nothing is saved to history until git commit. Lose the folder before committing and staged work is gone.
git commit saves everything currently in your working directory
False. It saves only what is staged. Edits you made but never git added stay behind as "changes not staged" — a classic surprise.
Once you commit, the old versions are overwritten
False. Each commit points to its parent, so old snapshots stay reachable. Committing adds a checkpoint; it never erases previous ones.
git clone gives you only the latest version of the project
False. Clone downloads the entire history — every commit and branch — which is what lets you work offline with a full backup.
Deleting a branch with git branch -d deletes its commits
False (usually). It only removes the label; commits already merged into another branch remain in history. Unmerged commits become hard to reach, which is why -d refuses to delete them.
A fast-forward merge creates a new merge commit
False. Fast-forward just slides the branch pointer forward because there was nothing to reconcile. A merge commit (with two parents) appears only in a three-way merge.
git fetch immediately updates your working files with remote changes
False. fetch downloads remote commits (updating origin/main) but does not touch your working directory or current branch. You still need a merge (or pull) to integrate them.
git pull is a single atomic command with no hidden steps
False. pull is literally fetch + merge. Knowing this explains why a pull can produce a merge conflict — the merge half failed.

Spot the error

git commit -m "fix" right after editing a file, expecting the edit to be saved — what's wrong?
The edit was never staged. Without git add, the file stays "modified but unstaged," so the commit either records nothing or an older staged version. Run add first.
git branch feature-x then keep working, expecting new commits to land on feature-x — what's wrong?
git branch only creates the label; it does not switch to it. HEAD still points at the old branch, so commits land there. You needed git checkout feature-x (or checkout -b).
git push origin main on a fresh clone with local commits, but push is rejected — likely cause?
The remote (origin) main has commits you don't have locally. Push refuses to overwrite them; you must git pull (fetch + merge) first, then push the reconciled history.
echo "*.pyc" > .gitignore after already committing a .pyc file, expecting it to vanish from tracking — what's wrong?
.gitignore only stops untracked files from being added. A file already tracked keeps being tracked; you must git rm --cached it to stop tracking.
git add . then git commit believing you made two separate logical commits — what's the trap?
git add . stages all changes at once, so they land in a single commit. To craft atomic commits you must add files (or hunks) selectively before each commit.
git checkout main; git merge feature while feature still had uncommitted edits — which of two different things actually happens?
Two distinct behaviours, don't conflate them. (1) git checkout main may itself refuse if your uncommitted edits would be overwritten by the switch. (2) If the checkout succeeds, git merge still only combines committed history — those unstaged edits are simply not part of the merge and get left sitting in your working directory.

Why questions

Why does Git have a staging area instead of committing everything directly?
To let you build atomic commits — group only the related changes and leave unrelated edits for a separate commit, keeping history readable and easy to revert.
Why is a commit hash 40 hex characters (SHA-1) and not just a counter like 1, 2, 3?
Because Git is distributed: many people commit independently with no central authority to hand out numbers. A content-based hash (a 20-byte SHA-1, shown as 40 hex characters) is globally unique without coordination.
Why does each commit store a pointer to its parent?
To form a chain (history graph) so Git can reconstruct any past state, walk backwards, and identify the common ancestor needed for merges.
Why fetch before you merge, instead of always pulling?
fetch updates your origin/main snapshot so you can inspect the incoming commits (via git log origin/main) before integrating them, letting you merge deliberately rather than blindly.
Why is HEAD important when committing?
HEAD marks the current branch/commit you're on — the "you are here" pointer. New commits attach where HEAD points, so HEAD decides which branch receives your work.
Why commit small logical changes separately instead of one big commit?
So each change can be reverted, reviewed, or bisected independently. If normalization has a bug, you drop that one commit without losing the cleaning function.

Edge cases

What does git status show in a brand-new repo right after git init with no files added?
"No commits yet" and any files listed as untracked. There is no history and nothing staged; Git sees the files but isn't tracking them until you add.
Can you commit with an empty staging area?
Normally no — Git says "nothing to commit." (You'd need the explicit --allow-empty flag to force an empty snapshot, e.g. to mark a milestone.)
What happens to a file you add, then edit again before committing?
The commit records the staged version, not the newest edit. The re-edit sits as a fresh "not staged" change, so the file appears in both staged and unstaged lists at once.
What is a "detached HEAD" and how do you get one?
When you git checkout <a-commit-hash> (instead of a branch), HEAD points straight at a commit with no branch label in between. New commits you make there belong to no branch, so they're easily lost — to keep them, create a branch (git checkout -b keep-me) before switching away.
If two branches modify the same line differently and you merge, what happens?
Git cannot decide automatically, so it produces a merge conflict, marks the spot in the file, and pauses for you to resolve it manually before completing the merge commit.
What does merging a branch into itself, or merging with nothing new, produce?
Git reports "Already up to date" and does nothing — there are no unique commits to bring in, so no snapshot is created.
Is a freshly created branch's commit history different from the branch it was made on?
No. At creation both branches point to the same commit and share all past history. They diverge only once you add new commits to one of them.
Recall Fast self-check

Which command saves to permanent history? ::: git commit (after git add stages the changes). Does git branch new switch you onto new? ::: No — use git checkout -b new to create and switch. What does HEAD point to? ::: The current branch (or, in detached state, a bare commit) — the place your next commit attaches. What is origin? ::: The default name for the remote copy of your repo (e.g. on GitHub). git pull = ? ::: git fetch + git merge.


Related paths: 1.4.12-GitHub-workflows · 1.4.10-Command-line-interface · 2.1.3-Jupyter-notebooks · 3.2.5-Experiment-tracking · 5.3.2-Model-versioning · 4.1.8-CI-CD-pipelines