Модуль 8 · Урок 30 із 58

Atomic commits: staging, history і safe undo

Хороший commit — не просто точка backup, а reviewable change з однією причиною. Index дозволяє відокремити finished logic від debug print або сусіднього refactor. Undo починається з питання: зміна local/uncommitted чи вже shared у history?

git addatomic commitrestorerevert

Безпечна Git-практика модуля 8

Пакет містить тільки synthetic repository files, локальний Python CLI, tests і read-only history verifier. Не додавайте .git, .env, credentials, персональні або production-дані, machine paths чи зовнішні endpoints.

Завантажити практичний пакет →

Stage exact intent, а не всю теку

git add src/parser.py tests/test_parser.py
git add -p
git diff --staged --check
git diff --staged

git add копіює current content paths до index. Interactive patch mode дозволяє stage окремі hunks, але не виправляє змішаний design автоматично. Якщо hunk містить дві причини, спершу зробіть кодову зміну чіткішою.

Atomic означає одну причинну одиницю

Commit має будуватися, проходити relevant tests і пояснювати одну завершену зміну. «Update files» не передає intent. Корисний subject використовує imperative form і називає observable outcome: Reject duplicate case identifiers. Body пояснює why, constraints і non-obvious tradeoff, а не переповідає diff line by line.

Review test: чи можна revert цього commit без випадкового видалення іншої незалежної фічі?

Commit фіксує index

git commit -m "Reject duplicate case identifiers"
git show --stat --oneline HEAD
git show --check HEAD

Commit не бере автоматично всі unstaged edits. Після commit перевірте status і сам snapshot. --amend створює новий commit замість попереднього; це нормально для ще не shared local history, але змінює commit ID.

Restore має source, destination і scope

git restore --worktree path/to/file
git restore --staged path/to/file
git restore --source=HEAD --staged --worktree path/to/file

Перша команда відкидає unstaged content у working tree, друга прибирає path з index, не стираючи working-tree edit. Обидві можуть втратити незбережену роботу, тому спершу inspect diff і, якщо зміна потрібна, збережіть patch або commit на окремій branch.

Revert додає inverse commit до shared history

git revert <commit>

revert не видаляє старий commit: він записує нову зміну, що скасовує effect selected commit. Це зазвичай audit-friendly для вже pushed history. Конфлікт означає, що current context не дозволяє механічно застосувати inverse; його треба вирішити й перевірити tests.

Reset — не універсальна кнопка undo

reset рухає references і залежно від mode змінює index/working tree. --hard може знищити tracked uncommitted edits. У базовому workflow використовуйте explicit restore для local files/index, revert для shared commit і окремий backup branch для history surgery.

СитуаціяБезпечний default
Зайвий staged pathgit restore --staged path
Unstaged experiment точно не потрібенInspect diff → git restore path
Pushed commit треба скасуватиgit revert commit
Local commit треба переробитиBackup branch → deliberate amend/rebase

Definition of Done

  • Staged diff містить одну reviewable причину.
  • Commit message пояснює outcome та intent.
  • Tests запускаються до й після commit.
  • Restore/revert обираються за state і shared boundary.
  • Destructive reset не виконується без exact target, backup і inspection.

Методичні джерела

Урок, сценарії, пояснення й вправи створені SEOWORK. Посилання ведуть лише на офіційну документацію Git і GitHub.

Практична перевірка · урок 30 з 47

Закріпіть матеріал уроку

Три сценарні питання. Для зарахування уроку потрібно дати щонайменше дві правильні відповіді.

1. У файлі одночасно готовий bug fix і незавершений debug print. Який staging підхід найкращий?
2. Який критерій найкраще відрізняє atomic commit від просто малого commit?
3. Що фактично фіксує git commit без додаткових path flags у звичайному staged workflow?