graphite について
Graphite Skillは、Graphite(`gt`)でスタック型プルリクエストを作成、移動、管理するためのコマンドガイドです。ブランチスタックを扱う開発者向けに、提出やリベース、復旧の手順をまとめています。
主な機能
- 01スタックブランチの作成と修正
- 02ブランチスタックの移動と確認
- 03スタックをレビューに提出
- 04ブランチの並べ替えと親変更
- 05ブランチの再スタックと競合対応
- 06中断したリベースから復旧
活用シーン
- 01範囲を絞ったプルリクエストの連鎖を作成
- 02スタック内のブランチ間を移動
- 03スタックをmainにリベース
- 04スタック更新時の問題を解決
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ withgraphite/ agent-skills --skill graphiteインストール後、Claude Code で/graphiteを入力して読み込まれたか確認します。
詳細
Graphite スキル
Graphite(gt)を使って、スタック形式のプルリクエストを作成、移動、管理します。
クイックリファレンス
| やりたいこと | コマンド |
|---|---|
| 新しいブランチ/PRを作成する | gt create branch-name -m "message" |
| 現在のブランチを修正する | gt modify -m "message" |
| スタックを上に移動する | gt up |
| スタックを下に移動する | gt down |
| スタックの最上部に移動する | gt top |
| スタックの最下部に移動する | gt bottom |
| スタック構造を表示する | gt ls |
| スタックをレビューに提出する | gt submit --no-interactive |
| スタックを trunk にリベースする | gt restack |
| ブランチの親を変更する | gt track --parent <branch> |
| 現在のブランチ名を変更する | gt rename <new-name> |
| スタック内でブランチを移動する | gt move |
優れたPRとは?
重要度の高い順に、おおよそ次のとおりです。
- アトミック/自己完結型 - 他の変更に依存せず、単独で CI に合格し、安全にデプロイできます
- 意味上のスコープが狭い - モジュール X のみを変更する、またはモジュール X、Y、Z に同じ変更を加えます
- 差分が小さい - (目安として)差分の合計行数が少ない状態です
プルリクエストを作りすぎることを心配する必要はありません。 少ない数より多い数のプルリクエストを作成するほうが、常に望ましいです。
どんなに小さな変更でもPRにできます: 小さなPRによって、中規模/大規模のPRがより明確になります。
それぞれが単独でビルドに合格する限り、常にPRを増やすことを推奨してください。
ブランチ命名規則
スタック内のPRに名前を付けるときは、次の形式に従います。
terse-stack-feature-name/terse-description-of-change
たとえば、4つのPRからなるスタックは次のようになります。
auth-bugfix/reorder-args
auth-bugfix/improve-logging
auth-bugfix/improve-documentation
auth-bugfix/handle-401-status-codes
スタックの作成
基本的なワークフロー
- ファイルに変更を加えます
- 変更をステージングします:
git add <files> - ブランチを作成します:
gt create branch-name -m "commit message" - スタック内の各PRについて繰り返します
- 提出します:
gt submit --no-interactive
未追跡ブランチへの対処(worktreeでよく発生)
ブランチを作成する前に、現在のブランチが追跡されているか確認します。
gt branch info
「ERROR: Cannot perform this operation on untracked branch」と表示された場合:
方法A(推奨):一時的に追跡してから、親を付け替える
- 現在のブランチを追跡します:
gt track -p main - 通常どおり
gt createでスタックを作成します - すべてのブランチを作成した後、最初に作成したブランチの親を main に付け替えます:
gt checkout <first-branch-of-your-stack> gt track -p main gt restack
方法B:変更をスタッシュして main から始める
git stashgit checkout main && git pull- 新しいブランチを作成して、スタッシュを戻します:
git checkout -b temp-working && git stash pop gt track -p mainとgt createを使って作業を進めます
スタック内の移動
# Move up one branch (toward top of stack)
gt up
# Move down one branch (toward trunk)
gt down
# Jump to top of stack
gt top
# Jump to bottom of stack (first branch above trunk)
gt bottom
# View the full stack structure
gt ls
スタックの変更
現在のブランチを修正する
git add <files>
gt modify -m "updated commit message"
ブランチの順序を変更する
gt move を使って、スタック内のブランチの順序を変更します。gt create --insert を使おうとするより簡単です。
スタックの親を付け替える
フィーチャーブランチの上にスタックを作成したものの、main を基点にしたい場合:
# Go to first branch of your stack
gt checkout <first-branch>
# Change its parent to main
gt track --parent main
# Rebase the entire stack
gt restack
ブランチ名を変更する
gt rename new-branch-name
コミットを未ステージの変更に戻す
変更をすでにコミットしているものの、別の形で再スタックしたい場合:
# Reset the last commit, keeping changes unstaged
git reset HEAD^
# Reset multiple commits (e.g., last 2 commits)
git reset HEAD~2
# View the diff to understand what you're working with
git diff HEAD
提出前
スタックが main を起点としていることを確認する
gt submit を実行する前に、最初のPRの親が main であることを確認します。
gt ls
最初のブランチの親が main 以外の場合:
gt checkout <first-branch>
gt track -p main
gt restack
検証を実行する
各PRを作成した後、適切なリンティング、ビルド、テストを実行します。
- プロジェクトの CLAUDE.md を参照して、具体的なコマンドを確認します
- 検証に失敗した場合は、問題を修正して変更をステージングし、
gt modifyを使います
PRの提出と更新
スタックを提出する
gt submit --no-interactive
PR の説明を更新する
送信後、gh pr edit を使って適切なタイトルと説明を設定します。
重要: PR の説明に Bash のヒアドキュメントは使用しないでください。シェルのエスケープ処理によって、Markdown の表やコードブロックなどが崩れます。代わりに、以下の手順に従います。
Writeツールを使って、完全な Markdown コンテンツを含む/tmp/pr-body.mdを作成します--body-fileを指定してgh pr editを実行します
gh pr edit <PR_NUMBER> --title "stack-name: description" --body-file /tmp/pr-body.md
PR の説明には、以下を含める必要があります。
- スタックのコンテキスト:このスタックのより大きな目標は何ですか?
- 変更内容(小さな変更の場合は任意):なぜではなく、何を変更したのかをごく簡潔に記述します
- 理由:何が変更のきっかけですか?なぜこの解決策を選んだのですか?スタックにどう適合しますか?
例(警告機能を追加する 3 件の PR からなるスタックの PR の場合):
## Stack Context
This stack adds a warning on the merge button when users are bypassing GitHub rulesets.
## Why?
Users who can bypass rulesets (via org admin or team membership) currently see no indication
they're circumventing branch protection. This PR threads the bypass data from the server to
enable the frontend warning (PR 2) to display it.
トラブルシューティング
| 問題 | 解決策 |
|---|---|
| "Cannot perform this operation on untracked branch" | まず gt track -p main を実行します |
| スタックが誤ったブランチを親にしている | gt track -p main を実行してから、gt restack を実行します |
| PR の順序を変更したい | gt move を使います |
| restack 中に競合が発生した | 競合を解決してから、git rebase --continue を実行します |
| PR を分割したい | コミットをリセットし(git reset HEAD^)、必要な変更だけを再ステージして、新しいブランチを作成します |
| ブランチを削除する必要がある(非対話型) | gt delete <branch> -f -q |
gt restack で無関係な競合が発生する | 代わりに対象を指定して git rebase <target> を使います(下記参照) |
| 競合の途中で rebase が中断された | ファイルが解決済みでもステージされていない可能性があるため確認し、git add と git rebase --continue を実行します |
上級編:複雑なスタックでの外科的な Rebase
深くネストされたスタックに多数の兄弟ブランチがある場合、gt restack は問題を引き起こすことがあります。
- 自分のスタックだけでなく、必要なブランチをすべて restack します
- まったく無関係なブランチで競合が発生することがあります
- 全か無かの処理であり、対象を絞り込むのが困難です
gt restack ではなく git rebase を使う場合
以下の場合は、直接 git rebase を使います。
- スタック内の特定のブランチだけを更新したい
gt restackで無関係なブランチの競合が発生する- rebase 中に古くなったコミットをスキップする必要がある
対象を指定した Rebase のワークフロー
# 1. Checkout the branch you want to rebase
git checkout my-feature-branch
# 2. Rebase onto the target (e.g., updated parent branch)
git rebase target-branch
# 3. If you hit conflicts:
# - Resolve the conflict in the file
# - Stage it: git add <file>
# - Continue: git rebase --continue
# 4. If a commit is obsolete and should be skipped:
git rebase --skip
# 5. After rebase, use gt modify to sync graphite's tracking
gt modify --no-edit
中断された Rebase からの復旧(コンテキストのリセット)
(Claude のセッションでコンテキストが尽きた場合などに)rebase が中断された場合:
-
状態を確認します:
git status # Look for "interactive rebase in progress" and "Unmerged paths" -
「unmerged」ファイルを確認します。すでに解決済みで、競合マーカーが残っていない場合があります。
-
すでに解決済みの場合は、そのままステージして続行します:
git add <resolved-files> git rebase --continue -
競合マーカーがまだ残っている場合は、まず競合を解決してからステージし、続行します。
スタックからのブランチの削除
# Delete a branch (non-interactive, even if not merged)
gt delete branch-to-delete -f -q
# Also delete all children (upstack)
gt delete branch-to-delete -f -q --upstack
# Also delete all ancestors (downstack)
gt delete branch-to-delete -f -q --downstack
フラグ:
-f/--force:マージまたはクローズされていなくても削除します-q/--quiet:--no-interactiveを暗黙的に指定し、出力を最小限にします
中間ブランチを削除すると、子ブランチは自動的に親ブランチを基点として restack されます。追跡先を手動で更新する必要がある場合:
gt checkout child-branch
gt track --parent new-parent-branch