Version-control a config directory and recover from mistakes
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
- Create a config file, commit it, then make and commit several changes with meaningful messages. Confirm
git log --onelinereads sensibly. - Use
git blameto find which commit last changed a specific line, andgit log -p <file>to see every change to it. This is the administrator's core use: "why is this timeout 900?". - Demonstrate that
git diffshows unstaged changes only: edit a file,git addit, and confirm plaingit diffnow shows nothing whilegit diff --stagedshows the change. - 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). - Recover from the hard reset: use
git reflogto find the lost commit andgit reset --hard <hash>to restore it. State the asymmetry: committed work is very hard to lose, uncommitted work is easy. - Show
.gitignoreaffects only untracked files: commit a.env, add it to.gitignore, and confirm it is still tracked untilgit rm --cached. - On a branch, use
git revertto undo a commit by adding a new one, and explain why that is the safe choice on shared history whereresetis 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.