3.2 Staging Area, Differences, and Safe Undo
Prerequisites: Creating Your First Git Repository
Estimated time: 15 minutes
Practice environment: Continue using the temporary repository from the previous page
You are ready to continue when: you can identify which layer a change belongs to and then choose between restore, amend, or revert accordingly
The first snapshot is saved. Before undoing a later change, locate it: is it unstaged, staged, or committed? Those states require different operations. Start with status and diff so the command restores the intended layer.
Two Common Types of Diff
printf '%s\n' "print('hello, Git')" > main.py
git diff
git add main.py
git diff --staged
git commit -m 'Update greeting'git diff: Between the working directory and the staging area.git diff --staged: Between the staging area andHEAD.git show HEAD: Within a single commit.
Unstaged: Restore Workspace Files
printf '%s\n' "print('temporary draft')" >> main.py
git diff
git restore -- main.py
git diffThe first diff shows the draft line; the second should be empty. Restore overwrites the working file with its staged version. Git generally cannot recover text it never saved, so read git diff before proceeding. If you need to preserve your current state, copy the files, create a temporary branch and commit, or use git stash push -u; by default, stash does not include untracked files, and restoration may result in conflicts.
Staged: Undo Only add
printf '%s\n' 'draft' > notes.txt
git add notes.txt
git restore --staged -- notes.txt
git status --shortnotes.txt is still in the workspace, just no longer part of the next commit.
Most Recent Local Commit: amend
git add notes.txt
git commit -m 'Add notes'
printf '%s\n' 'more context' >> notes.txt
git add notes.txt
git commit --amend --no-editThe amend command creates a new commit, causing its ID to change. This operation is only safe when the history hasn't been depended upon by others. If you're working on a personal remote branch and need to update it, coordinate first and prefer using git push --force-with-lease; it will still rewrite remote history and is not a substitute for a regular push.
Already Shared: revert
git revert --no-edit HEADrevert adds a reverse commit that preserves the original history, making it suitable for shared branches. Merge commits require checking the parent commit on the main line and cannot be blindly applied.
git reset --hard simultaneously moves references and overwrites the staging area and working directory. This is not presented as a typical undo tool in this section.
The Boundaries of .gitignore
printf '%s\n' '__pycache__/' '*.pyc' '.env' > .gitignore
mkdir -p __pycache__
touch __pycache__/cache.pyc .env
git status --shortIgnore rules only affect untracked paths. Files already tracked in the repository must be reviewed and explicitly untracked using git rm --cached -- path before changes can be committed. If sensitive keys have already been committed or pushed, rotate the keys first. Deleting files from the workspace or adding them via .gitignore will not remove secrets from repository history.
Large objects also remain in history. Datasets and artifacts are typically stored in dedicated storage; when versioning is necessary, evaluate Git LFS. Using git filter-repo to clean history will alter commit IDs and requires backups and coordination with repository users.
These ignore files are only for observing the current state, never committed or carried forward into future branch experiments:
rm -r -- __pycache__
rm -- .env .gitignore
git status --shortEnsure the output is empty before proceeding to create a new branch.