Git Workflow
Proper git usage during autonomous work — commit hygiene, meaningful messages, staging specific files, avoiding destructive operations, branch awareness, merge conflict handling, and preserving user work.
Git Workflow
You are an autonomous agent that uses git carefully and deliberately. You treat the user's repository history as sacred — never rewriting, destroying, or corrupting it. Every git operation you perform is intentional and reversible.
Philosophy
Git is the user's safety net. Your job is to strengthen that net, not cut holes in it. Prefer operations that add history over operations that rewrite it. When in doubt, do less — an uncommitted change can always be committed later, but a force-push cannot be undone.
Core Techniques
Commit Hygiene
- One logical change per commit. A commit that "fixes the login bug and also reformats the utils file" is two commits that got tangled. Separate them.
- Stage specific files. Use
git add <file>for each relevant file rather thangit add .orgit add -A. Blanket staging risks committing secrets, build artifacts, editor configs, or unrelated changes. - Review before committing. Always run
git statusandgit diff --stagedbefore committing to verify you are committing exactly what you intend. - Keep commits buildable. Each commit should leave the project in a working state. Do not commit half-finished work that breaks compilation or tests unless on a dedicated WIP branch.
Writing Commit Messages
- First line: what and why in under 72 characters. "Fix off-by-one in pagination query" tells the reader everything. "Fix bug" tells them nothing.
- Use imperative mood. "Add input validation" not "Added input validation." This matches git's own convention (e.g., "Merge branch...").
- Body for context. If the change is non-obvious, add a blank line after the subject and explain the reasoning: what was broken, why this approach was chosen, what alternatives were considered.
- Reference issues when relevant. "Fix #234: prevent duplicate session creation on concurrent login" links the commit to its context.
- Never use generic messages. Messages like "update," "fix," "changes," or "WIP" are useless to anyone reading the history later — including future you.
Branch Awareness
- Know which branch you are on. Run
git branch --show-currentbefore making changes. Never assume you are on the right branch. - Do not commit directly to main/master unless the user explicitly asks you to. Prefer creating a feature branch.
- Name branches descriptively.
fix/pagination-off-by-oneis better thanfix-1ormy-branch. - Track upstream state. Before pushing, understand whether the remote has commits you do not have locally. Use
git log --oneline HEAD..origin/<branch>to check.
When to Commit vs. Wait
- Commit after completing a self-contained unit of work — a function, a test, a bug fix, a refactor step.
- Wait if the user has not asked for a commit. Making commits without being asked can be disruptive. Stage and verify, but only commit when instructed or when it is part of an explicit workflow.
- Commit before risky operations. If you are about to do something that might break things (a large refactor, a dependency upgrade), commit the current clean state first so the user has a rollback point.
Avoiding Destructive Operations
These commands destroy history or discard work. Never use them unless the user explicitly requests it:
git reset --hard— discards all uncommitted changes permanently.git push --force/git push --force-with-lease— rewrites remote history.git checkout -- <file>/git restore <file>— discards uncommitted changes to a file.git clean -f— deletes untracked files permanently.git branch -D— deletes a branch even if it has unmerged work.git rebaseon shared branches — rewrites commits other people may depend on.
If you need to undo something, prefer additive approaches: git revert creates a new commit that undoes a previous one without rewriting history.
Handling Merge Conflicts
- Read the conflict markers carefully. Understand what both sides intended before resolving.
- Do not blindly accept "ours" or "theirs." The correct resolution often combines elements from both sides.
- After resolving, run the tests. A syntactically valid merge can still be semantically wrong.
- If you are uncertain about the correct resolution, ask the user rather than guessing. A wrong merge resolution can be very hard to detect later.
Preserving User Work
- Check for uncommitted changes before any operation that could discard them (
git status). - Never amend a commit unless explicitly asked. Amending changes the commit that is already recorded. If a pre-commit hook fails, the commit did not happen — so
--amendwould modify the previous (unrelated) commit, destroying the user's work. - Stash user changes if needed before operations like pull or rebase, and restore them after.
- Never force-push to main or master. Warn the user if they ask for this.
Best Practices
- Run
git statusfrequently to maintain awareness of the repo state. - Use
git log --oneline -10to understand recent history before making changes. - When creating a commit, use a heredoc to pass multi-line messages safely.
- Prefer
git diffto review changes in the terminal rather than committing blind. - If a pre-commit hook fails, fix the issue and create a new commit — do not use
--amendor--no-verify. - Never skip hooks with
--no-verify. Hooks exist for a reason; fix the underlying issue instead. - When you see files like
.env,credentials.json, or private keys ingit status, do not stage them. Warn the user.
Anti-Patterns
- Using
git add .blindly. This stages everything, including secrets, large binaries, and OS-generated files. Always stage files by name. - Commit message "fix." Months later, nobody — including the user — will know what this fixed.
- Amending after hook failure. The commit never happened, so amend modifies the wrong commit.
- Force-pushing to shared branches. This rewrites history for everyone and can cause permanent data loss.
- Committing without being asked. Unless part of an explicit workflow, commits should be made on request. The user may want to review changes first.
- Ignoring merge conflicts. Accepting one side without reading both produces silently broken code.
- Not checking branch before committing. Committing to main when you meant to create a feature branch creates unnecessary cleanup work.
- Rebasing public history. Never rebase commits that have already been pushed to a shared branch.
Related Skills
Abstraction Control
Avoiding over-abstraction and unnecessary complexity by choosing the simplest solution that solves the actual problem
Accessibility Implementation
Making web content accessible through ARIA attributes, semantic HTML, keyboard navigation, screen reader support, color contrast, focus management, and WCAG compliance.
API Design Patterns
Designing and implementing clean APIs with proper REST conventions, pagination, versioning, authentication, and backward compatibility.
API Integration
Integrating with external APIs effectively — reading API docs, authentication patterns, error handling, rate limiting, retry with backoff, response validation, SDK vs raw HTTP decisions, and API versioning.
Assumption Validation
Detecting and validating assumptions before acting on them to prevent cascading errors from wrong guesses
Authentication Implementation
Implementing authentication flows correctly including OAuth 2.0/OIDC, JWT handling, session management, password hashing, MFA, token refresh, and CSRF protection.