safe-git
safe-git
Announce at start: "I'm using the safe-git skill to verify safe git operations."
Gate 1 — Before starting any work on a task
1a — Confirm you're on a feature branch
-
Run
git branch --show-current -
If result is
mainormaster→ STOPDo not proceed. Create a feature branch first:
git checkout -b <descriptive-branch-name>Then begin work on the feature branch.
1b — Confirm your branch is up-to-date
-
Run
git fetchto update remote tracking info -
Check if an upstream is configured:
git rev-parse @{u} 2>/dev/nullIf this fails (no upstream set) → branch is local-only. Skip to Gate 2.
-
Run:
git log HEAD..@{u} --oneline-
Returns nothing → branch is up-to-date. Proceed.
-
Returns commits → WARN the user:
Your local branch is behind the remote by N commit(s). Starting work now risks merge conflicts and duplicated effort.
Recommended: pull before starting.
git pullIf you choose to proceed without pulling, inform the user of the risk.
Note: If
git log @{u}..HEAD --onelinealso returns commits, the branches have diverged. This requires manual resolution — do not blindlygit pull. Warn the user explicitly and stop until they decide how to proceed. -
Gate 2 — Before staging files
- Run
git statusand review ALL listed changes - Identify which files are relevant to the current task
- Stage specific files only:
git add path/to/file1 path/to/file2WARNING:
git add .andgit add -Aare FORBIDDEN — they silently include unrelated changes. Stop immediately. Do not run these commands. Explain the situation to the user. - Verify staged files:
Confirm only intended files appear. If unintended files are staged, unstage them:git diff --staged --statgit restore --staged <file>
Gate 3 — Before any commit
If recovering from a pre-commit hook failure:
The pre-commit hook rejected the commit — no commit was created. After fixing the issue, use a fresh commit:
git commit -m "your message"
git commit --amend is FORBIDDEN in this case. Stop immediately. Do not run this command. Explain the situation to the user. The commit you would be amending is the last pushed commit, not a new one.
Before any other use of git commit --amend:
Run:
git log @{u}..HEAD --oneline
Note: If this command fails with "no upstream configured" or similar error, the branch is local-only (never pushed). Amend is safe.
-
Returns commits → amend is safe (those commits are unpushed)
-
Returns nothing → amend is FORBIDDEN, all commits are already pushed. Stop immediately. Do not run this command. Explain the situation to the user.
Use a fresh commit instead:
git commit -m "your message"
Gate 4 — Before creating a PR
-
Run
git branch --show-current -
If result is
mainormaster→ STOP immediately. Do not proceed.You cannot create a PR from main/master. Create a feature branch first:
git checkout -b <descriptive-branch-name> # move your changes to the feature branch if needed
Recommended Hook Setup
Install these hooks in each repo to add mechanical protection independent of this skill.
pre-commit — blocks direct commits to main/master
Save to .git/hooks/pre-commit and run chmod +x .git/hooks/pre-commit:
#!/bin/bash
branch=$(git branch --show-current)
if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then
echo "ERROR: Direct commit to $branch is not allowed. Create a feature branch first."
exit 1
fi
pre-push — blocks pushing to main/master
Save to .git/hooks/pre-push and run chmod +x .git/hooks/pre-push:
#!/bin/bash
while read local_ref local_sha remote_ref remote_sha; do
if [[ "$remote_ref" =~ refs/heads/main ]] || [[ "$remote_ref" =~ refs/heads/master ]]; then
echo "ERROR: Pushing to main/master is blocked. Use a feature branch and PR."
exit 1
fi
done
exit 0