Version-controlling Claude Code skills is straightforward: skills are plain-text SKILL.md files stored under .claude/skills/, and git tracks them identically to any other source file. No special tooling, no skill-specific extensions, no migration steps. At Agent Engineer Master (AEM), every skill library we build for clients ships with git version control as a baseline requirement. If your project already has a git repository, you're 90% of the way there.
TL;DR: Skills are plain-text files stored in
.claude/skills/. Git tracks them natively. Add the directory to your existing repo, use branches to test changes, and keep user-level skills in a separate personal dotfiles repo. No special tooling required. Every change is committed with full history, so rollbacks take one command.
Git is used by 93% of developers as their primary version control system (Stack Overflow Developer Survey, 2022). Your skill files benefit from the same workflow you already know.
Why Does Version Control Matter for Skill Files?
A SKILL.md file is your specification for how Claude behaves on a task. The same reason you version-control application code applies to skills: you need a way to see what changed, roll back a regression, and collaborate without overwriting each other's work.
Skill regressions are subtle. You update a description field to improve activation rates, and suddenly a section of your output contract stops being followed. Without git history, isolating the cause requires guesswork. With git, git diff HEAD~1 .claude/skills/code-review/SKILL.md shows you the exact change. One command, not an hour of memory archaeology.
"The failure mode isn't that the model is bad at the task — it's that the task wasn't specified tightly enough. Almost every production failure traces back to an ambiguous instruction." — Simon Willison, creator of Datasette and llm CLI (2024)
Version control makes that traceable. An ambiguous instruction that crept in on Tuesday is findable on Wednesday.
How Do I Set Up Git for My Claude Code Skills?
Add your .claude/skills/ directory to your existing project repository. That directory is where Claude Code looks for project-level skills, and it sits naturally inside any git-managed project. No migration, no special configuration: one git add .claude/skills/ and every SKILL.md file from that point is tracked with full commit history.
my-project/
.claude/
settings.json
skills/
code-review/
SKILL.md
references/
review-standards.md
commit-message/
SKILL.md
src/
package.json
git add .claude/skills/
git commit -m "chore: add initial Claude Code skill library"
From that point, every change to any SKILL.md or reference file is tracked. git log .claude/skills/ shows the full modification history. git blame .claude/skills/code-review/SKILL.md shows which commit introduced each line and who made the change.
One thing to check before the first commit: do any reference files inside the skills folder contain credentials, API keys, or sensitive data? Skill reference files accumulate domain knowledge, and that knowledge sometimes includes secrets. Audit the content before pushing to a remote repository.
How Do I Test a New Skill Version Without Breaking the Current One?
Create a branch, edit the skill, test it in a fresh Claude Code session, then merge. The fresh session is the critical step: Claude Code loads skills from disk at startup, so a new session sees only the current file contents, no authoring context carried over. That is the test that reflects production behavior.
git checkout -b skill/improve-code-review-trigger
# Edit .claude/skills/code-review/SKILL.md
# Open a new Claude Code session
# Test the skill against 5-10 representative prompts
git add .claude/skills/code-review/SKILL.md
git commit -m "refactor: tighten trigger to reduce false positives on review mentions"
git checkout main
git merge skill/improve-code-review-trigger
The critical step is testing in a fresh session. In the editing session, Claude has seen your changes in conversation context. A fresh session is what skill engineers call a "Claude B test": it sees only what's in the file, with no prior conversation context. That is the test that reflects real production behavior.
Each skill's name and description loads into the system prompt at session startup, costing approximately 100 tokens per skill in context overhead (Claude Code Skill Engineering research, 2026). Anthropic's official context window documentation shows skill descriptions loading as a named startup block totalling 450 tokens for a small library (Anthropic, Claude Code Docs, 2025); a 40-skill library costs roughly 1,500 tokens at startup for descriptions alone (Anthropic Engineering Blog, 2025). A focused branch-and-test workflow avoids the cost of discovering a regression after the change is already on main.
One limitation worth naming: git tracks structural file changes, not behavioral regressions. A diff can show you that a description changed from 12 words to 15 words, but it cannot tell you whether Claude now triggers the skill on prompts it should ignore. Git is a necessary condition for skill version control, not a sufficient one. Behavioral testing against a fixed set of prompts (a "Claude B test" on the branch) is the check git cannot perform for you.
We tag milestone skill versions in commissioned builds. When we deliver version 1.0 of a client skill, they can run git diff v1.0 .claude/skills/skill-name/SKILL.md at any future point to see exactly what diverged from the original specification. Clean version history is part of the deliverable.
Should I Commit User-Level Skills to Git?
No. User-level skills live at ~/.claude/skills/ in your home directory. These are personal skills that apply to every project you open. Committing them to a project repo pushes your personal workflow preferences onto every developer who clones the project. Those preferences belong to you, not the codebase.
If you want to version-control your personal skill library, keep it in a separate dotfiles repository. A ~/.dotfiles/claude-skills/ directory with a symlink to ~/.claude/skills/ is a clean approach that lets your skills travel across machines without polluting project history.
For more on the distinction between personal and project skills, see What's the Difference Between Project-Level and User-Level Skills?.
How Do I Track Skill Changes Across a Team?
Use pull requests. When a team member wants to update a shared skill, they branch, edit, open a PR, and get a review before merge. The review step enforces the same discipline on skill changes that it enforces on application code: no behavioral change reaches the shared library without another engineer confirming the intent and verifying a fresh-session test.
The review checklist for a SKILL.md change:
- What specifically changed in the description or instructions?
- Has this been tested in a fresh Claude Code session (Claude B test)?
- Do the existing evals.json test cases still pass?
At roughly the 30-skill threshold, the review process shifts from optional to necessary. Below that count, informal commit access works. Above it, drift between what different team members expect from the same skill creates inconsistency that is hard to debug (Claude Code Skill Engineering research, 2026).
Merge conflicts are a real cost, not a theoretical one. Across 143 open-source projects and 556,911 commits, 19.32% of merges resulted in a conflict (Ghiotto, Murta et al., Empirical Software Engineering, 2019). SKILL.md files are short, so conflicts are fast to resolve, but that frequency makes the case for enforcing the PR workflow before conflicts accumulate. The same study found that 75.23% of conflict cases required the developer to reason about program logic to resolve them. Even a one-line description change can carry that cognitive load if the intent behind it is unclear.
PR review workflows are now standard practice. The 2024 State of Software Quality report found that 64% of teams conduct code reviews for every pull request (49% blocking, 15% non-blocking) (Codacy, 2024). Applying the same gate to skill changes is not overhead; it is the same discipline already in place for the rest of the codebase.
GitHub's Octoverse data covering 986 million commits shows a clear trend toward smaller, more focused pull requests (GitHub, Octoverse 2025). The same discipline applies to skill changes: one commit per behavioral change, not one commit per session.
A useful commit message convention for skill changes names the behavioral change, not just the file:
refactor: tighten description to stop triggering on check queries(useful)update SKILL.md(not useful)
For a broader look at sharing skills within a team, see How Do I Share Skills with My Team?.
What Should I Add to .gitignore for Skill Files?
In most cases: nothing. The SKILL.md files, reference files, and assets folder all belong in version control. Claude Code generates no runtime artifacts inside .claude/skills/, so there is nothing to exclude by default. The only exception is a reference file that contains credentials or secrets, which should not be there in the first place.
If a reference file does contain secrets, add a specific exclusion pattern rather than removing the whole skills directory from tracking:
# Prevent committing sensitive reference files
.claude/skills/**/credentials.md
.claude/skills/**/*-secrets.md
FAQ
Does git track changes to reference files inside a skill folder?
Yes. Every file inside .claude/skills/skill-name/ is tracked, including reference files, assets, and templates. A change to a reference file is as significant as a change to SKILL.md itself. Commit them together so the history shows the full state of the skill at each point in time.
What happens if two team members edit the same skill simultaneously?
Git flags the merge conflict as it would for any other file. SKILL.md conflicts are usually small because the files are short. The description field on a single line is the most common conflict point: two developers updating the trigger condition at the same time will collide there.
Should I squash skill commits or keep them as separate entries?
Keep individual commits during development, squash before merging to main. This preserves granularity during active iteration while keeping the main branch history clean. One commit per meaningful behavioral change, not one commit per file touched.
Can I use semantic versioning for Claude Code skills?
Yes. Tag releases with git tag v1.0.0 once a skill passes its full evals suite. The version tag is a reference point: this is the skill as delivered, before any subsequent modifications. Useful for auditing whether production behavior has drifted from the original specification.
How do I roll back a skill change that broke something?
Run git revert on the commit that introduced the change, or git checkout HEAD~1 -- .claude/skills/skill-name/SKILL.md to restore the previous version of that specific file. Test in a fresh session to confirm the behavior returned to the prior state.
Can I store skills in a monorepo alongside application code?
Yes. Claude Code resolves the nearest .claude/ directory to the current working directory. A monorepo can have a root-level skill library shared across packages, with project-specific skills in subdirectories. Skills closer to the working directory take precedence.
Last updated: 2026-05-03