Version-control a config directory and recover from mistakes

short · 30 min · Objective 4.4

Task

Put a configuration directory under git, then practise the recoveries that make git worth using for an administrator: seeing who changed a line, undoing a commit safely, and getting back work you appeared to have destroyed with reset --hard.

Steps

  1. Create a config file, commit it, then make and commit several changes with meaningful messages. Confirm git log --oneline reads sensibly.
  2. Use git blame to find which commit last changed a specific line, and git log -p <file> to see every change to it. This is the administrator's core use: "why is this timeout 900?".
  3. Demonstrate that git diff shows unstaged changes only: edit a file, git add it, and confirm plain git diff now shows nothing while git diff --staged shows the change.
  4. Undo the last commit three ways and observe the difference: reset --soft HEAD~1 (keeps it staged), reset HEAD~1 (keeps it in the tree), reset --hard HEAD~1 (destroys it).
  5. Recover from the hard reset: use git reflog to find the lost commit and git reset --hard <hash> to restore it. State the asymmetry: committed work is very hard to lose, uncommitted work is easy.
  6. Show .gitignore affects only untracked files: commit a .env, add it to .gitignore, and confirm it is still tracked until git rm --cached.
  7. On a branch, use git revert to undo a commit by adding a new one, and explain why that is the safe choice on shared history where reset is not.

Verify

cd ~/lab-git
git blame config.conf | head -1
git diff --stat >/dev/null && git add -A && git diff --cached --stat | tail -1
git reflog | head -5                       # shows where HEAD has been
git ls-files | grep -q '\.env' && echo ".env still tracked despite .gitignore"

The reflog listing is the safety net worth internalising: a reset --hard that appeared to destroy a commit has not, for about ninety days, and the reflog is how you get it back. The .env still appearing in ls-files is the gitignore-only-affects-untracked trap.

Notes

Committed work is very hard to lose and uncommitted work is easy, which is the whole argument for committing early and often. The reflog covers commits; nothing covers an uncommitted change you reset --hard over -- which is why that command is the most destructive one in ordinary git use.