I wanted to make Git work more efficient.
At first, I wrote shell scripts and put prompts telling Claude to run them in .md files. Pasting them into Claude Code ran the scripts and produced good results.
In an IDE such as Cursor, pasting prompts into split terminal panes was convenient. Warp, which I use these days, is a terminal with an attached editor, so copying prompts from files was awkward. Converting them to slash commands seemed likely to solve that too.
While I was at it, I thought I might as well turn all my Git tasks into commands: branch creation, commits, pushes, PRs, and merges. Automating the whole workflow seemed like something that would pay off later.
But once there were seven commands, managing them became difficult. Copying them into every project was cumbersome too.
So I made a plugin.
The Finished Result
# Marketplace 추가
/plugin marketplace add nasodev/nasodev-marketplace
# 플러그인 설치
/plugin install git-workflow@nasodev-marketplaceInstalling it adds seven slash commands:
| Command | Description |
|---|---|
/git:0.check | Check Git status and configuration |
/git:1.branch | Create a new branch |
/git:2.sync | Synchronize the main branch |
/git:3.commit | Commit changes |
/git:4.push | Push to the remote |
/git:5.pr | Create a pull request |
/git:6.merge | Merge into main |
I numbered them in workflow order so it would be clear what to do first.
Why a Plugin?
Initially, I just placed the command files in the project's .claude/commands/ directory.
.claude/commands/
├── git-branch.md
├── git-commit.md
└── git-push.md
That worked, but had problems:
- Copying into every project—copy the files whenever a new project starts
- Cumbersome updates—copy scripts back into all projects whenever they change
- No version tracking—no clear record of which project has which version
With a plugin:
# 한 번만 설치하면 모든 프로젝트에서 사용
/plugin install git-workflow@nasodev-marketplace
# 업데이트도 한 줄
/plugin update git-workflow@nasodev-marketplacePlugin Structure
A Claude Code plugin is simpler than you might expect.
claude-git-workflow/
├── .claude-plugin/
│ └── plugin.json # 플러그인 메타데이터
├── commands/
│ ├── git:0.check.md # 슬래시 커맨드 정의
│ ├── git:1.branch.md
│ └── ...
├── scripts/
│ ├── git-check.sh # 실제 실행될 스크립트
│ ├── git-branch.sh
│ └── ...
└── README.md
plugin.json
{
"name": "git-workflow",
"description": "Git workflow automation with interactive scripts",
"version": "1.3.0",
"author": {
"name": "nasodev",
"email": "creationand2017@gmail.com"
},
"repository": "https://github.com/nasodev/claude-git-workflow",
"license": "MIT"
}Command File (git:0.check.md)
---
name: git:0.check
description: "Git 상태 확인 (isolated fork)"
context: fork
allowed-tools: [Bash]
model: haiku
---
# Git 상태 및 설정 확인
현재 저장소의 브랜치, 사용자 설정, 작업 상태를 확인한다.
---
**반드시 Bash tool로 아래 스크립트를 실행해라. 다른 방법은 허용하지 않는다.**
\`\`\`bash
./scripts/git-check.sh
\`\`\`Two key points:
- Frontmatter: isolated execution requires
context: forkalong withname,allowed-tools, andmodel - Explicit instructions: “Always execute the script with the Bash tool.” Without this, Claude sometimes explains the script instead of running it
Why a Marketplace Is Needed
The plugin is built—how do I distribute it?
Claude Code uses a marketplace-based plugin system.
# 이렇게 직접 설치 불가
/plugin install nasodev/claude-git-workflow # 에러Plugins can be installed only through a marketplace:
# 1. Marketplace 등록
/plugin marketplace add nasodev/nasodev-marketplace
# 2. 그 다음에 설치 가능
/plugin install git-workflow@nasodev-marketplaceMarketplace Structure
A marketplace is also a GitHub repository:
nasodev-marketplace/
├── .claude-plugin/
│ └── marketplace.json # 플러그인 목록
├── README.md
└── LICENSE
marketplace.json
{
"name": "nasodev-marketplace",
"owner": {
"name": "nasodev",
"email": "creationand2017@gmail.com"
},
"metadata": {
"description": "Claude Code plugins by nasodev",
"version": "1.0.0"
},
"plugins": [
{
"name": "git-workflow",
"description": "Git workflow automation with interactive scripts",
"version": "1.3.0",
"source": {
"source": "url",
"url": "https://github.com/nasodev/claude-git-workflow.git"
}
}
]
}Add the plugin to the plugins array to make it installable by users.
Script Highlights
git-check.sh: Current Status at a Glance
./scripts/git-check.shRunning it shows the following:
- Repository: name, path, and remote URL
- Branch: current branch, default branch, and ahead/behind status
- User Configuration: local, global, and effective settings
- Working Directory: counts of staged, unstaged, and untracked files
- Recent Commits: the five most recent commits
Showing Local vs Global user settings together is particularly useful for avoiding the question, “Whose name will this commit use?”
git-push.sh: Linting Across Languages
It runs lint checks automatically before pushing:
# 프로젝트 타입 자동 감지
if [ -f "package.json" ]; then
npm run lint
elif [ -f "pyproject.toml" ]; then
ruff check . # 또는 pylint
elif [ -f "go.mod" ]; then
go vet ./...
elif [ -f "Cargo.toml" ]; then
cargo clippy
fiIt detects Node.js, Python, Go, Rust, and Java projects and runs the appropriate linter.
git-branch.sh: Safe Branch Creation
# 변경사항이 있으면 자동 stash
git stash push -m "Auto stash before branch switch"
# 브랜치 생성
git checkout -b feature/new-feature
# stash 복원
git stash popIt switches branches safely even when there are uncommitted changes.
Context Isolation: context: fork
Running the commands repeatedly exposed a problem. After /git:0.check and then /git:3.commit, the previous conversation context kept accumulating. That wasted tokens, and sometimes the commands referred to earlier results and behaved unexpectedly.
With context: fork, the command runs in an isolated context:
---
name: git:0.check
description: "Git 상태 확인 (isolated fork)"
context: fork
allowed-tools: [Bash]
model: haiku
---Required Fields
A few additional fields are needed for context: fork to work:
| Field | Description | Example |
|---|---|---|
name | Command identifier | git:0.check |
allowed-tools | Available tools | [Bash] |
model | Model to run | haiku, sonnet, opus |
Including only description and context: fork does not provide isolation. name, allowed-tools, and model must also be present for “(forked execution)” to appear and actual isolation to occur.
Choosing a Model
Not every command needs the same model:
| Model | Purpose | Command |
|---|---|---|
haiku | Simple script execution | 0.check, 1.branch, 2.sync, 4.push, 6.merge |
sonnet | Message writing required | 3.commit, 5.pr |
opus | Complex analysis or judgment | (Not used in this plugin) |
haiku is fast and inexpensive, making it suitable for commands that only need to run a script.
sonnet is used to write commit messages or PR descriptions. A stronger model is needed to create meaningful messages in Korean.
opus is used when complex analysis or judgment is needed. It suits advanced tasks such as code review and architectural design.
Testing Installation
Let's install it:
# 터미널에서
claude plugin marketplace add nasodev/nasodev-marketplace
# ✔ Successfully added marketplace: nasodev-marketplace
claude plugin install git-workflow@nasodev-marketplace
# ✔ Successfully installed plugin: git-workflow@nasodev-marketplace
claude plugin list
# ❯ git-workflow@nasodev-marketplace
# Version: 1.3.0
# Scope: user
# Status: ✔ enabledRestart Claude Code after installation to use the /git: commands.
Installation Scopes
Plugins can be installed in three scopes:
| Scope | Description | Use case |
|---|---|---|
user | Available in every project (default) | Shared tools |
project | Current project only; tracked by git | Team sharing |
local | Current project only; ignored by git | Personal settings |
# 글로벌 설치 (기본값)
claude plugin install git-workflow@nasodev-marketplace
# 프로젝트별 설치
claude plugin install -s project git-workflow@nasodev-marketplaceSince the default is user, installing once makes /git:* commands available in any project.
GitHub Repositories
- Plugin: https://github.com/nasodev/claude-git-workflow
- Marketplace: https://github.com/nasodev/nasodev-marketplace
Wrapping Up
Claude Code plugins are easier to build than I expected.
- In
commands/, create.mdfiles - Write
.claude-plugin/plugin.json - Create a marketplace repository and register the plugin
Then you can use it as /my-command in every project.
If you have a recurring workflow, try turning it into a plugin.





Comments
Korean and English pages share this conversation.
Loading comments…