mcpField
M
mergify-stack

mergify-stack

github.com/mergifyio開発3287 回インストール1 日前に更新
リポジトリ

mergify-stack について

mergify-stack は、Mergify CLI で Git ブランチを短く依存関係のあるスタックとして管理するワークフロースキルです。コーディングエージェント向けにスタック編集と PR 更新の手順を示し、各コミットが単独で CI を通ることを求めます。

主な機能

  1. 01スタックブランチと PR の作成・更新
  2. 02スタック同期とコミット・PR 状態の確認
  3. 03非対話型コマンドによるコミットの書き換え
  4. 04コミットメッセージと PR 内容の連動
  5. 05単独で CI を通るコミットとドラフト PR

活用シーン

  1. 01無関係な作業を別ブランチに分割
  2. 02マージ後に既存スタックを同期
  3. 03エージェントセッションでコミットを修正・並べ替え

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mergifyio/mergify-cli --skill mergify-stack

インストール後、Claude Code で/mergify-stackを入力して読み込まれたか確認します。

詳細

翻訳後に原文が更新されています。最新の内容は原文をご確認ください。

Mergify スタックワークフロー

スタックの考え方

ブランチはスタックです。スタックは短く、焦点を絞って保ちましょう:

  • スタックには、互いに依存し合うコミットのみを含めるべきです
  • 理由:スタックが長くなるほど、マージに時間がかかります

プロアクティブなスタック管理:

  • 既存のスタックを独立したスタックに分割できる場合は、分割を提案してください
  • 新しいことを依頼されたとき:別のブランチで実行できる場合は、そうするか、不明な場合は確認してください
  • 無関係な変更には、デフォルトで新しいブランチを作成してください

基本的な規約

  • プッシュ: mergify stack push を使用してください(git push は決して使用しないでください)
  • 修正: git commit --amend を使用してください(問題を修正するために新しいコミットを作成しないでください)
  • amend 時の注記: すでに PR があるコミット(つまりプッシュ済みのコミット)を amend する場合、mergify stack push の前に mergify stack note を付けて、そのコミットをなぜ amend したのかを記録してください。この注記は PR の「Revision history」コメントと JSON マーカーに表示されるため、レビュアーは差分を見なくても理由を確認できます。
  • スタック途中の修正: まずローカルの変更をすべてスタッシュし(git stash -u)、次に mergify stack edit <SHA-or-Change-Id-prefix> を使って対象コミットで rebase を一時停止します。git commit --amend で amend し、その後 git rebase --continue、続いて mergify stack push、最後に git stash pop を実行します。非対話式です — この用途で git rebase -i は決して使用しないでください。(mergify stack edit を引数なしで呼び出すと、完全に対話式の git rebase -i にフォールバックし、エージェントのコンテキストではハングします — 必ずコミットのプレフィックスを渡してください。)
  • 並べ替え: まずローカルの変更をすべてスタッシュし(git stash -u)、次に手動の git rebase -i の代わりに mergify stack reorder(すべてのコミットを希望する順序で列挙)または mergify stack move(単一のコミットを移動)を使用してください — 非対話式で、GIT_SEQUENCE_EDITOR のクォート問題を回避できます
  • Fixup: まずローカルの変更をすべてスタッシュし(git stash -u)、次に mergify stack fixup <SHA>... を使ってコミットをその親に折り込みます(列挙したコミットのメッセージは破棄されます)。非対話式です — この用途で git rebase -i は決して使用しないでください。
  • Squash: まずローカルの変更をすべてスタッシュし(git stash -u)、次に mergify stack squash SRC... into TARGET [-m "msg"] を使って複数のコミットを 1 つに結合します。任意でカスタムメッセージを指定できます。非対話式です — この用途で git rebase -i は決して使用しないでください。
  • Reword: まずローカルの変更をすべてスタッシュし(git stash -u)、次に mergify stack reword <SHA> -m "new message" を使ってコミットのメッセージをその場で変更します。-m を指定した場合は非対話式です — この用途で git rebase -i は決して使用しないでください。
  • Drop: まずローカルの変更をすべてスタッシュし(git stash -u)、次に mergify stack drop <SHA>... を使ってスタックからコミットを削除します。非対話式です — この用途で git rebase -i は決して使用しないでください。
  • コミットのタイトル: Conventional Commits に従ってください(例: feat:, fix:, docs:)
  • PR のタイトルと本文: mergify stack はコミットメッセージのタイトルを PR のタイトルに、コミットメッセージの本文を PR の本文にコピーします — そのため、コミットメッセージは PR の説明であるかのように書いてください。PR に表示されるべきものすべて(チケット参照、コンテキスト、テスト計画)は、必ずコミットメッセージに含めてください。
  • チケット参照: チケットやイシューの参照(例: MRGFY-1234、Fixes #123)はコミットメッセージの本文に含めてください。PR に別途追加しないでください。
  • PR のライフサイクルは mergify stack が完全に管理します: gh pr edit や GitHub MCP で PR のタイトル、本文、ラベルを決して編集しないでください — 次のプッシュで上書きされます。PR を手動でクローズまたはマージしないでください — mergify stack が PR のライフサイクル全体(作成、更新、クリーンアップ)を処理します。
  • ドラフト PR: PR を ready-for-review に決してしないでください — すべての PR はドラフトのままにします。ユーザーがレビュー後に手動でドラフトを解除します。
  • 各コミットは単独で CI を通過する必要があります: スタック内のすべてのコミットはそれぞれ独立した PR になります。各 PR は個別に CI を実行するため、すべてのコミットは自己完結していなければなりません — スタック内の後続のコミットに依存せず、単独でコンパイルし、リンターを通過し、テストを通過する必要があります。フォーマットやリンティングの修正が必要な場合は、それを問題を導入したコミットに含める必要があり、後続のコミットに先送りしてはいけません。

よくある間違い

間違い正しい方法理由
git pushmergify stack pushgit push はスタック管理をバイパスし、PR の関係を壊します
lint/タイポを修正するための新しいコミットgit commit --amend(HEAD)または git commit --fixup <SHA> + git rebase --autosquash(スタック途中)各コミット = 1 つの PR。修正コミットは不要な追加 PR を生み出します
gh pr edit --title "..."コミットメッセージを編集してから mergify stack pushPR のタイトル/本文はプッシュのたびにコミットメッセージから上書きされます
gh pr merge または gh pr closePR のライフサイクルは完全に管理されているため、何もしないPR のライフサイクルはスタックツールによって完全に管理されます
main 上での git commitまず mergify stack new <name>mergify stack push はデフォルトブランチでは失敗します
コミットを修正するための git rebase -imergify stack fixup <SHA>非対話型 — LLM/エージェントセッション内で動作し、エディタが起動されません
コミットを squash するための git rebase -imergify stack squash A B into X [-m "..."]非対話型 — LLM/エージェントセッション内で動作し、エディタが起動されません
コミットメッセージを変更するための git rebase -imergify stack reword <SHA> -m "..."非対話型 — LLM/エージェントセッション内で動作し、エディタが起動されません
スタック途中のコミットを修正するための git rebase -imergify stack edit <SHA-or-Change-Id-prefix> の後に git commit --amend、そして git rebase --continue非対話型 — エディタを起動せずに対象コミットで rebase を一時停止します
コミットを削除するための git rebase -imergify stack drop <SHA>...非対話型 — LLM/エージェントセッション内で動作し、エディタが起動されません
GIT_SEQUENCE_EDITOR='sed -i ...' git rebase -i(あらゆる変種)mergify stack {edit,fixup,squash,reorder,move} のいずれか手作りのシーケンスエディタスクリプトは壊れやすく、一般的な書き換えにはすでに非対話型のコマンドが存在します
lint 修正を後続のコミットに先送りするその原因となったコミットに修正を含める各コミットは独立して CI を実行するため、後続のコミットが以前のコミットを救うことはありません
ダーティなワークツリーでの rebase/reorder/checkout/syncまず git stash -u を実行し、その後 git stash popコミットされていない変更はこれらの操作中に失われるか、競合を引き起こします
説明なしでプッシュ済みコミットを amend するmergify stack push の前に mergify stack note -m "why"理由が PR の Revision history テーブルと JSON マーカーに記録されるため、レビュアーは差分を見なくても変更を理解できます

コマンド

mergify stack new NAME       # Create a new stack/branch for new work
mergify stack push           # Push and create/update PRs (also registers as a GitHub-native stack by default)
mergify stack push --no-github-native  # ...without registering it as a GitHub-native stack
mergify stack checkout BRANCH    # Checkout an existing stack from GitHub (e.g. someone else's)
mergify stack checkout PR_URL    # Same, from any PR in the stack — middle included
mergify stack sync           # Fetch trunk, remove merged commits, rebase
mergify stack list           # Show commit <-> PR mapping for current stack
mergify stack list --json    # Same, but machine-readable JSON output
mergify stack reorder C A B  # Reorder all commits (pass SHA or Change-Id prefixes)
mergify stack move X first   # Move commit X to the top of the stack
mergify stack move X last    # Move commit X to the bottom of the stack
mergify stack move X before Y  # Move commit X before commit Y
mergify stack move X after Y   # Move commit X after commit Y
mergify stack fixup X              # Fold commit X into its parent (drops X's message)
mergify stack fixup X Y Z          # Fold each into its parent (multi-fixup)
mergify stack squash X into Y      # Reorder X adjacent to Y, fold X into Y (keeps Y's message)
mergify stack squash X Y into Z -m "msg"  # Fold X Y into Z with a custom message
mergify stack reword X -m "msg"    # Change commit X's message non-interactively
mergify stack reword X             # Change commit X's message via $GIT_EDITOR (TTY only)
mergify stack edit X               # Pause the rebase at X so you can `git commit --amend` it (X is required; no-arg form is interactive)
mergify stack drop X               # Drop commit X from the stack
mergify stack drop X Y Z           # Drop multiple commits in one rebase
mergify stack note -m "why"        # Attach an amend reason to HEAD (shown in PR revision history)
mergify stack note <SHA-or-Change-Id-prefix> -m "why"  # Attach to a specific commit in the stack
mergify stack note --append -m "more"                  # Append to an existing note
mergify stack note --remove                            # Remove the note from a commit

mergify stack checkout を使用すると、GitHub 上に存在するスタック(たとえば同僚のスタック)をチェックアウトできます。引数には、スタックのリモートブランチ名(どのようなプレフィックスであってもよく、作者名が含まれているとは想定しません)、またはスタック内の任意のプルリクエストの URL(途中のものを含む)を指定します。スタックされたすべての PR をフェッチし、ローカルブランチを作成して、トラッキングを設定します。

ローカルブランチの名前は、デフォルトではスタックブランチから自分のスタックブランチプレフィックスを除いたものになるため、feature/login からプッシュしたスタックは feature/login として戻り、その後の mergify stack push で同じ PR が更新されます。自分のプレフィックス配下にないスタック(同僚のもの)の場合は、最後のセグメントが使用され、チェックアウト時に警告が表示されます。それらのコミット上で作業することはできますが、そのブランチから mergify stack push を実行すると、同僚のプルリクエストを更新するのではなく、別のスタックが作成されます。名前を上書きするには --branch を使用します。プルリクエストの URL にはそれ自体の owner/repo が含まれるため、その形式では --repository は無視されます。

mergify stack sync を使用すると、スタックを最新の状態にできます。最新のトランクをフェッチし、マージされた PR を検出し、それらのコミットをローカルブランチから削除して、残りのコミットをリベースします。既存のスタックで新しい作業を始める前に実行してください。

mergify stack list を使用すると、どのコミットがプッシュ済みか、それらがどの PR に対応するか、スタックがリモートと同期しているかを確認できます。各 PR の CI ステータス、レビューステータス、マージコンフリクトも表示されます。詳細なチェック名とレビュアー名を表示するには --verbose を使用します。出力をプログラムで解析する必要がある場合は --json を使用します。これには完全な CI チェックの詳細とレビューデータが含まれます。

GitHub ネイティブスタック(デフォルトで有効)

mergify stack push はデフォルトでスタックを GitHub 自身の Stacks API に登録するため、GitHub はそれをスタックとしてレンダリングします。呼び出しごとに --no-github-native でオプトアウトするか、リポジトリごとに git config mergify-cli.stack-github-native false でオプトアウトできます。

Change-Id、ブランチレイアウト、リビジョン履歴は変わらず、静かに機能を縮退させます。API が利用できない場合(古い GitHub Enterprise、この機能を持たないリポジトリ)には、プッシュは not registered on GitHub と報告し、これまでとまったく同じように成功します。

知っておくべき 3 つのこと:

  • スタックには少なくとも 2 つのプルリクエストが必要です。 GitHub は 1 つの PR のスタックを拒否するため、単一の変更のスタックは通常の PR のままです。また、メンバーを失った 2 つの PR のスタックは再登録されるのではなく解散されます。
  • Depends-On: ヘッダーはなくなります。 登録されたスタックは まさに 2 つのプルリクエスト間の依存関係であるため、CLI はそのコピーを PR の説明に二重に書き込むのをやめます。これはフラグではなく登録に基づいて決まります。プッシュが not registered on GitHub に縮退した場合、ヘッダーは同じプッシュ内で書き戻され、Mergify はスタックの順序付けを続けます。どちらの場合でもコミットメッセージには一切触れません。ヘッダーは常に、レンダリングされた PR の説明の中にのみ存在していました。
  • スタックのコメントもなくなります。 GitHub は登録されたスタックのメンバーをプルリクエストページに一覧表示するため、CLI は「This pull request is part of a Mergify stack」という固定の表を投稿するのをやめ、古いプッシュが各オープンメンバーに残したものを削除します。ヘッダーと同じく登録に基づいて決まります。縮退したプッシュは表の投稿と更新を続けます。なぜなら、それ以外にスタックを示すものがないからです。リビジョン履歴のコメントはどちらの場合でも変更されません。GitHub はそれに似たものを何もレンダリングしません。
  • 登録は PR のマージ方法を変えます。 スタックが登録されている間、GitHub はそのメンバーに対して従来のマージエンドポイント (PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge → 403) を拒否します。これは GitHub の契約であり、私たちのものではありません。これが --no-github-native が存在する理由です。

プッシュは低コストのままです。コミットのリフレッシュ(amend、reword、force-push)は登録をそのままにし、変更を上に追加すると同じスタックが拡張されます。プルリクエストのベースを移動させるプッシュ(並べ替え、削除、途中への変更の挿入)だけが、まず登録を解散し、最後に再構築します。なぜなら GitHub は PR がスタックされている間、ベースブランチの変更を一切拒否するからです。したがって、中断されたプッシュはスタックを単に未登録のままにします——半分登録された状態には決してなりません。また、Depends-On: ヘッダーが失われたままになることもあります。これらはプッシュの最後に復元されるためです。mergify stack push を再実行すれば両方とも解決します。すべてのプッシュが説明を再レンダリングし、スタックの現在の形状から Depends-On: マーカーを再計算するからです——--keep-pull-request-title-and-body を使用した場合も同様で、その場合の説明はコミットメッセージではなくプルリクエスト自身の本文から再レンダリングされ、マーカーは引き継がれるのではなく、依然として削除されて再追加されます。

修正ノート

mergify stack note は、コミットがなぜ修正されたかを記録します。ノートはスタックとともに移動します:

  • 理由はコミット SHA に対して refs/notes/mergify/stack の下にローカルに保存されます。
  • mergify stack push 時に、理由はチェンジのリビジョン履歴に取り込まれます。プッシュされた先頭コミットのノートは、リビジョン履歴全体 (人間が読めるダイジェスト + `` JSON マーカー) に置き換えられます。機械可読な信頼できる情報源は PR コメントではなく Git notes です。PR の「リビジョン履歴」コメントはそれらからレンダリングされます。
  • マージ時に、Mergify は先頭コミットの履歴ノートをマージ/スカッシュコミットにコピーするため、ベースブランチで git log --notes=mergify/stack を実行すると、各チェンジがなぜ改訂されたかが表示されます。

ノートを付けるタイミング — すでに PR がオープンされている (つまり少なくとも一度はプッシュされている) コミットを修正または書き換えるたびに。ノートは「なぜこのリビジョンは異なるのか?」に答えるもので、レビュアーが新旧の SHA を diff して調べる必要がなくなります。

ワークフロー — mergify stack push の前にノートを付けます:

# Edit HEAD, then:
git commit --amend
mergify stack note -m "address review: rename foo() to bar()"
mergify stack push

# Or for a mid-stack commit (after the rebase that amended it):
mergify stack note <SHA-or-Change-Id-prefix> -m "fix lint reported in CI"
mergify stack push

ノートはリビジョン単位ではなくコミット単位です。修正 (またはその他の履歴書き換え) のたびに新しいコミット SHA が作成されるため、新しい SHA に対して再度 mergify stack note を実行する必要があります。以前のノートは古い SHA に付いたままで、引き継がれることはありません。--append は、現在の対象コミットにすでにノートがあり、別の理由を追加したい場合にのみ使用してください。--remove はノートをクリアするために使用します。最後のプッシュ以降に変更されていないコミットのノートは保持されますが、新しいリビジョン行は追加されません。

重要: コミットする前に必ずブランチを確認する

何かをステージまたはコミットする前に、常に現在のブランチを確認し、スタックの状態を評価してください:

git branch --show-current
mergify stack list
  • main (またはリポジトリのデフォルトブランチ) にいる場合: まずフィーチャーブランチを必ず作成する必要があります
  • main に直接コミットしないでください — mergify stack push が失敗します
  • この確認は git commit の後ではなく、git add の前に実行する必要があります

重要: ワークツリーを変更する操作の前にローカルの変更を stash する

履歴を書き換えたりブランチを切り替えたりする操作を実行する前に、コミットされていない変更がないか確認し、stash してください:

git status --short          # Check for uncommitted changes
git stash -u                # Stash tracked + untracked changes if any

この確認が必要な操作:

  • mergify stack edit <commit> (スタック途中の修正)
  • mergify stack reorder / mergify stack move
  • mergify stack fixup
  • mergify stack squash
  • mergify stack reword
  • mergify stack drop
  • mergify stack checkout
  • mergify stack sync
  • mergify stack new (新しいブランチに切り替えます)
  • git checkout <branch>

操作が完了したら、stash した変更を復元します:

git stash pop

この手順を省略すると、コミットされていない作業は気づかないうちに失われるか、リベースの競合を引き起こします。

新しい作業の開始

新しい作業を開始する、新しいフィーチャーを作成する、または現在のスタックと無関係な何かに取り組むよう依頼された場合:

  1. 現在のブランチを確認: git branch --show-current
  2. 新しいスタックを作成: mergify stack new <branch-name>
    • パターン type/short-description (例: feat/add-login、fix/memory-leak) に従った説明的なブランチ名を使用してください
  3. コミットを作成: conventional commits に従ってください
  4. プッシュ: mergify stack push

既存のスタックへの追加

既存のフィーチャーブランチでの作業を続ける場合:

  1. 現在のブランチを確認: git branch --show-current
    • 正しいブランチにいる場合: そのままコミットを進めます
    • main にいる場合: まず git checkout <branch> でフィーチャーブランチに切り替えるか、新しいスタックを作成してください

競合の解決

リベースが競合を引き起こした場合 (git rebase -i または mergify stack push 中):

  1. エディターで競合を解決します
  2. 解決したファイルを git add でステージします
  3. git rebase --continue で続行します

中止する場合: git rebase --abort

解決後、mergify stack push を実行して更新されたスタックを同期します。

コメント