Activities

メンテナのGit作業時間は、3つのアクティビティに費やされます。

  • コミュニケーション (45%)

    一般的な設計、ユーザーの質問への回答、バグレポートの診断に関するメーリングリストでのディスカッション。パッチのレビューや、コメントや、代替案の提案や、パッチの拒否。

  • インテグレーション(統合) (50%)

    貢献者からの新しいパッチを適用しながら、小さな間違いを見つけて修正し、統合ブランチとテストブランチを混ぜっ返し、結果をプッシュし、リリースを区切り、アナウンスを行います。

  • 自身の開発作業 (5%)

    自身が思う痒い所に手を入れ、提案パッチシリーズを送信します。

The Policy

統合に関するポリシーは、 機能リリースが行われるたびにメーリングリストに定期的に投稿される "A Note from the maintainer" (メンテナーからのメモ)メッセージで非公式に言及されています:

  • 機能リリースには vX.Y.0 の番号が付けられており、機能、パフォーマンス、使いやすさなど、あらゆる分野でのバグ修正と機能拡張が、デグレ無しで含まれることを目的としています。

  • メンテナンス・リリースには vX.Y.Z という番号(但し (0 < Z))が付けられており、 対応する vX.Y.0 機能リリースと以前のメンテナンスリリース vX.Y.W (但し W<Z)の、 バグ修正のみが含まれていることを意味します。

  • 「masterブランチは、 次の機能リリースの準備に使用されます。 言い換えると、 vX.Y.0 が最新の機能リリースである場合、 ある時点で「master」ブランチの先端が vX.(Y+1).0 としてタグ付けされます。

  • 「maint」ブランチは、次のメンテナンスリリースの準備に使用されます。 機能リリース vX.Y.0 が作成された後、「maint」ブランチの先端がそのリリースに設定され、バグ修正がブランチに蓄積され、ある時点で、ブランチの先端に vX.Y.1, vX.Y.2, 等のタグが付けられます。

  • 「next」ブランチは、 (1) 価値のある目標を持ち、 (2) 日常使用に適したかなり良好な状態にあり、 (3) ただしデグレがないことがまだ証明されていない変更(機能強化と修正の両方)を公開するために使用されます。 メーリングリストでの貢献者からのレビューが、 この判断を助けます。 トピックが「next」にマージされた後、 少なくとも7日間(7 calendar days)テストされ、 その後「master」にマージされます。

  • 「seen」ブランチは、 「next」に設定された基準(上記参照)をまだ満たしていない他の提案された変更を公開するために使用されますが、 「seen」にすべての変更が含まれるという保証はありません。 レビュアーからの反応がないトピックは取り上げられない場合があります。

  • 新しいトピックは、 明らかに正しくて緊急の場合を除き、 最初に「seen」にマージされます。 その場合、 直接「next」や「master」にマージされることがあります。

  • 「seen」に取り込まれたトピックが、 3暦週にわたって活動がなく、 「next」に進むのに十分な明確な合意が得られていない場合、 そのトピックは「seen」から破棄されることがあります。 関係者は依然としてそのトピックを復活させることができます。 このガイドラインの目的において、 「活動がない」(inactive)とは、 誰もそのトピックについて議論していない、 かつ、 新しいバージョンのトピックが投稿されていない、 かつ、 レビュー・コメントへの返答がない状態を指します。

  • 「master」と「maint」ブランチの先端は、人々がそれらの上に独自のカスタマイズを構築できるようにするために、巻き戻されることはありません。 新しい開発サイクルの早い段階で、「next」は「master」の先端に一度巻き戻されますが、それ以外の場合は、サイクルが終了するまで巻き戻されません。

  • 通常、「master」には「maint」のすべてが含まれ、「next」には「master」のすべてが含まれます。 「seen」には「next」にマージされたすべてのトピックが含まれていますが、「master」で直接再構築されています。

  • 「master」の先端は、タグ付けされたどのリリースよりも安定していることを意味しており、ユーザーはそれに従うことをお勧めします。

  • 「next」ブランチは新しいアクションが行われる場所であり、新しいトピックが「master」にマージされる前にデグレとバグが見つかるように、ユーザーはそれをテストすることをお勧めします。

  • 「next」にあるトピックに問題が見つかった場合、 そのトピックは「master」にマージされないようマークされます。 フォローアップのパッチはメーリングリストで議論され、 レビュー後にトピックに適用され、 その後トピックは(再度)「next」にマージされます。 「next」での通常のテストを経た後、 (修正された)トピック全体が 「master」にマージされます。

  • 機能リリースのための1つのリリース・サイクルは、 8〜10週間続くことが予想されます。 最終リリースの前に、 約1週間間隔でいくつかの「リリース候補」(release candidate)がタグ付けされ、 最初のリリース候補がタグ付けされる約1週間前に「プレビュー」(preview)リリースがタグ付けされます。

  • プレビュー・リリースがタグ付けされた後、 十分にレビューされたトピックは、 通常の7暦日を「next」で過ごすことなく「master」にマージされることがあります。 これは、 最終リリース前にリリース候補でバグが見つかり修正されることが期待されるためです。

  • 最初のリリース候補(release candidate)がタグ付けされた後、 貢献者は、 そのサイクル中に導入された新しいデグレ(regressions)を見つけて修正することに重点を置くよう強く推奨されます。 これは、 既存の古いバグや新機能の対応よりも優先されます。 トピックは「next」から「master」へのマージが停止し、 新しいトピックも「next」へのマージが停止します。 ただし、 サイクル中の新しいデグレに対する修正はこの限りではありません。

  • 機能リリースが行われた直後、 「maint」の先端はリリースを指すように早送り(fast-forward)されます。 「next」に保持されていたトピックは「master」にマージされ、 新しい開発サイクルが開始されます。

注意: v1.9.0リリース以前は、バージョン番号の構造が少し異なっていたことに注意してください。 vX.Y.Z は機能リリースであり、vX.Y.Z.W は vX.Y.Z のメンテナンスリリースでした。

Git のコードのほとんどの行は個々の貢献者によって書かれており、 それらの貢献はメーリングリストで公開されるメール形式のパッチとして提供されるため、 プロジェクトでは個々のコミットとそのコミットに至ったメールの Message-Id をマッピングして、 変更の起源を追跡できるようにしています。 この目的のために refs/notes/amlog のノートが使用され、 メンテナーのリポジトリーへ分割されたブランチとともに公開されます。

A Typical Git Day

メンテナの典型的なGitな一日は、以下のようにして上記のポリシーを実装します:

  • メーリングリストを走査します。 レビューコメント、提案などで返信します。あちこちの議論にクチバシを突っ込みます(Kibitz)。 メーリングリストから潜在的に使用可能なパッチを収集します。 1つのトピックに関するパッチは1つのメールボックスに送信されます(私はGnusでメールを読み、\C-o と入力して、メッセージをmbox形式のファイルに 保存/追加 します)。

  • メーリングリストで提起された、 誰も解決に名乗り出ていない問題に対応するパッチを自身で書き、 提出します。 他の貢献者と同じようにパッチを送信し、 他の貢献者からのパッチと同様にそれらを取り込みます(上記参照)。

  • 保存したメールボックスのパッチを確認します。タイプミス修正と、プログラムをキレイにするために提案されたログメッセージを編集し、リストから収集した対応を追加します。 パッチを編集して、ディスカッションからの「ええっと、これはこのようになっているはずです」な修正を組み込みます。

  • 収集されたパッチを分類し、 mastermaint の更新を処理します:

    • 明らかに、「maint」の先端に関連する正しい修正は、「maint」に直接適用されます。

    • 明らかに、「master」の先端に関連する正しい修正は、「master」に直接適用されます。

    • 他のトピックはこのステップでは処理されません。

      このステップは 「git am」で実行されます。

      $ git checkout master    ;# or "git checkout maint"
      $ git am -sc3 mailbox
      $ make test

      実際には、 master または maint に直接行くパッチはほとんどありません。

    • 明らかに、「maint」の先端に関連する正しい修正は、「maint」に直接適用されます。

    • 明らかに、「master」の先端に関連する正しい修正は、「master」に直接適用されます。

    • 他のトピックはこのステップでは処理されません。

      このステップは 「git am」で実行されます。

      $ git checkout master    ;# or "git checkout maint"
      $ git am -sc3 mailbox
      $ make test

      実際には、 master または maint に直接行くパッチはほとんどありません。

      git am を使用して電子メールで送られたパッチを適用すると、 Message-Id から適用されたコミットへのマッピングが自動的に amlog ノートに記録されます。 この機能が正しく動作しているかを定期的に git show -s --notes=amlog $commit で確認してください。

      このマッピングは、 「todo」ブランチにある post-applypatch フックを使用して維持されます。 このフックは、 パッチを適用する前にインストールする必要があります。 また、 リベース時に関連する amlog エントリを引き継ぐことも役立つため、 以下の設定が有用かもしれません:

      [notes]
             rewriteRef = refs/notes/amlog

      「cherry-pick」は設計上、 ノートを伝播しないため、 避けてください。 既存のコミットに修正を加える場合は、 単一のパッチのトピックであっても、 git commit --amend または git rebase を使用してください。

      公開リポジトリーの設定で、 refs/notes/amlog のプッシュ参照仕様(push refspec)がリモート設定(remote configuration)に含まれていることを確認してください。 以下にいくつかの設定例を示します:

      [remote "github"]
             url = https://github.com/gitster/git
             pushurl = github.com:gitster/git.git
             mirror
      [remote "github2"]
             url = https://github.com/git/git
             fetch = +refs/heads/*:refs/remotes/github2/*
             pushurl = github.com:git/git.git
             push = refs/heads/maint:refs/heads/maint
             push = refs/heads/master:refs/heads/master
             push = refs/heads/next:refs/heads/next
             push = +refs/heads/seen:refs/heads/seen
             push = +refs/notes/amlog
  • 「What’s cooking」メッセージの最後の号を確認し、マージの準備ができているトピックを確認します(topic→master と topic→maint)。 このステップを支援するために、 Meta/cook -w スクリプト( Meta/ には「todo」ブランチのチェックアウトが含まれています)を使用します。

    そして、マージを実行します。 この手順を支援するには、 Meta/Reintegrate -e スクリプト(後述)を使用します。

    $ Meta/cook -w last-issue-of-whats-cooking.mbox
    $ git checkout master    ;# or "git checkout maint"
    $ echo ai/topic | Meta/Reintegrate -e ;# "git merge ai/topic"
    $ git log -p ORIG_HEAD.. ;# final review
    $ git diff ORIG_HEAD..   ;# final review
    $ make test              ;# final review

    そして、マージを実行します。 この手順を支援するには、 Meta/Reintegrate -e スクリプト(後述)を使用します。

    $ Meta/cook -w last-issue-of-whats-cooking.mbox
    $ git checkout master    ;# or "git checkout maint"
    $ echo ai/topic | Meta/Reintegrate -e ;# "git merge ai/topic"
    $ git log -p ORIG_HEAD.. ;# final review
    $ git diff ORIG_HEAD..   ;# final review
    $ make test              ;# final review

    「master」の先端が更新された場合、 事前にフォーマットされたドキュメントも生成し、 その結果を git-htmldocs および git-manpages リポジトリーにプッシュしてください。

  • 残りのパッチを処理します:

    • 「master」に適用可能な非自明なもの(つまり、 「next」にあって「master」にないものに依存しないもの)は、 「master」の先端(または「master」よりも少し古い最新の機能リリース)から分岐した新しいトピック・ブランチに適用されます。 これには「master」に対する機能強化や非自明な修正が含まれます。 トピック・ブランチは ai/topic という形式で命名され、 ai は作者のイニシャルを表す2文字の文字列、 topic はトピックの説明的な名前(つまり「このシリーズは何についてか」)です。

    • 「maint」を対象とした明白でない修正が、「maint」の先端から分岐した新しいトピックブランチ(または最も古く、まだ関連するメンテナンスブランチ)に適用されます。 トピックには、 ai/maint-topic という名前を付けることができます。

    • 既存のトピックに関連する変更はブランチに適用されますが、以下のようになります:

      • 明らかに正しいものが最初に適用されます

      • 疑わしいものは廃棄されるか、先端近くで適用されます

    • 既存のトピックへの置換パッチは、 next にないコミットに対してのみ受け入れられます。

      最初のラウンドは以下のように行われます:

      $ git checkout ai/topic ;# or "git checkout -b ai/topic master"
      $ git am -sc3 --whitespace=warn mailbox

      既存のトピックを次のラウンドに置き換えるには、以下のようにします:

      $ git checkout master...ai/topic ;# try to reapply to the same base
      $ git am -sc3 --whitespace=warn mailbox

      切り離されたHEAD(detached HEAD)で新しいラウンドを準備し、それから以下のようにします

      $ git range-diff @{-1}...
      $ git diff @{-1}

      前回のラウンドから何が変わったかを再確認し、最後に以下のようにします

      $ git checkout -B @{-1}

      これで完結させます(最後のステップは、なぜ、すでに「next」にあるトピックが置き換えられず、段階的に更新されるかを示しています)。

      それが最初のラウンドであれ、 それ以降のラウンドであれ、 トピックが単独ではビルドできない場合や、 バグのために統合ブランチにマージするとビルドが壊れることがあります。 メーリングリストで既に明らかで些細な改善案が提案されている場合もあります。 メンテナーは、 問題を修正するために、 タイトルに SQUASH??? を含む追加のコミットをしばしば加え、 統合ブランチを公開して他の開発者がテストできるようにします。 これらの変更は、 メンテナーが100%確信を持っていないもので(些細なタイポ修正などは、 通常、 別個の SQUASH??? コミットとして適用せず、 修正が必要なパッチに直接組み込まれます)、 必要に応じて簡単に取り除けるようになっています。 これは元の著者が再提出(reroll)で修正を行うことが期待されています。

      • この時点で、 新しいトピック・ブランチが作成され、 既存のトピック・ブランチが更新されています。 統合ブランチである「next」と「jch」と「seen」を、それらを含むように更新する必要があります。

      • 「master」にマージされ、 かつ「maint」にもマージされるべきトピックがある場合、 それらを「maint」にマージし、 次のメンテナンス・リリースのリリース・ノートを更新してください。

      • 「What’s cooking」の最新号を再度レビューし、 「next」に十分な期間滞在しているトピックが「master」にマージする準備ができているか、 また以前に見た「seen」にあるトピックが肯定的なレビューを受け「next」にマージする準備ができているかを検討してください。

      • 「next」で十分に準備が整い、 「master」にマージされるべきトピックがある場合、 それらを「master」にマージし、 次の機能リリースのリリース・ノートを更新してください。

      • 「maint」に直接パッチが適用された場合、 「maint」を「master」にマージしてください。 そして、 その結果が望むものであることを確認してください。

        $ git checkout master
        $ git merge -m "Sync with 'maint'" --no-log maint
        $ git log -p --first-parent ORIG_HEAD..
        $ make test
      • しばしば「master」と「seen」の間を表し「next」よりやや先行する「jch」ブランチと、 残りのトピックを保持する「seen」ブランチを更新する準備をしてください。

        $ Meta/Reintegrate master..jch >Meta/redo-jch.sh

        その結果、 現在の「jch」を再構築するためにマージされるべきトピックをリストするスクリプトが得られます。 「seen」についても同じことを行ってください。

      • Meta/redo-jch.shMeta/redo-seen.sh スクリプトを確認してください。前者には ### match next という行があるはずです。 この行のアイデアは、 その行より前にリストされたトピックを「master」の先頭(top)にマージすることで、 「next」と同じツリーが得られるようにすることです。

      • 新しく作成されたトピックは通常「seen」の先端近くにマージされるので、 Meta/redo-seen.sh スクリプトの末尾に追加してください。 「seen」にあったトピックの中には、 「next」ではまだ完全に準備ができていないが、 準備が進んでいるものがあるかもしれません。 それらを Meta/redo-seen.sh から Meta/redo-jch.sh の末尾に移動してください。 「jch」を日常的に使用する最初のテスト・ユーザーとして使うことが期待されているので、 慎重に選択する必要があります。

      • これで、 「jch」の再構築とトピックを「next」にマージする準備が整いました。 先端が「next」にマージされていないブランチごとに、 以下の3つのいずれかが発生する可能性があります:

        • コミットはすべてnextにマージする価値があります。 トピックをnextにマージします。

        • 新しい部品は混合品質ですが、初期の部品はnextにマージする価値があります。 初期の部品をnextにマージします。

        • nextにマージする価値のあるものはありません。何もしません。

          この手順は、以前に作成した Meta/redo-jch.sh スクリプトを使用して支援されます。 すでに「next」にあるトピックにパッチが適用された場合、スクリプトはそれを ai/topic~1 としてリストします。 更新された「next」に新しいパッチを含めるには、 ~1 の部分を削除します。 なお、 除外したいモノの行はそのままにしてください。

          next になかったトピックを next にマージする必要がある場合は、 ### match next 行の前に追加します。 それから以下のようにします:

          $ git checkout --detach master
          $ sh Meta/redo-jch.sh -c1

          これは jch ブランチを最初から再構築します。 -c1 は、 ### で始まる最初の行(つまり、以前に追加した ### match next 行)でマージを停止するようにスクリプトに指示します。

          この時点で、 結果をビルド〜テストします。 セマンティックの競合が明らかになる場合があります(たとえば、トピックが変数の名前を変更し、 別のトピックが古い名前で変数への新しい参照を追加したとか)。 その場合、 最初に適切なマージ修正(merge-fix)を準備し(appendix 参照)、 そしてゼロから「jch」ブランチを再構築し、 「master」の先端から始めます。 今度 -C1 を使用し、 全てのトピックはマージしません。

          それから同一の事を「next」に行います。

          $ git checkout next
          $ sh Meta/redo-jch.sh -c1 -e

          -e オプションを使用すると、トピックの履歴からのマージメッセージと「What’s cooking」のコメントを編集できます。 同じトピックのセットが「master」にマージされるため、結果のツリーは jch^{/^### match next} とマッチする必要があります。 そうでなければ、 間違ったマージ(mismerge)をしてしまっています。 理由を調査し、 間違ったマージが検出されて修正されるまで続行しないでください。

          「next」のやり直し(redo)を開始する前に「master」が更新された場合、 以下のようにします

          $ git diff 'jch^{/^### match next}' next

          これは「master」に取り込まれた差分(「jch」にはありますが「next」にはまだないものです。 多くの場合、 これはリリース・ノートの更新です)を表示します。 そのような場合は、 「master」を「next」にマージし戻してください。

          $ git merge -m "Sync with 'master'" --no-log master

          全てOKになったら、 redo-jch.sh スクリプトで以下のようにクリーンアップします

          $ sh Meta/redo-jch.sh -u

          これにより、スクリプト内にリストされてる、「master」にすでにマージされているトピックを削除します。 これにより、「# match next」マーカーが失われる可能性があります。 もし「# match next」マーカーが失われたら、適切な場所に再度追加します。

      • 「jch」の先頭(top)の「seen」を再構築します。

        $ git checkout -B seen jch
        $ sh Meta/redo-seen.sh

        これが全てがOKになったら、redo-seen.sh スクリプトで以下のようにしてクリーンアップします

        $ sh Meta/redo-seen.sh -u

        実行して再確認(double check)します

        $ git branch --no-merged seen '??/*'
  • 「What’s cooking」メッセージを更新して、既存のトピック、新しく追加されたトピック、および段階的なトピックの更新を確認します。

    このステップは 「git am」で実行されます。

    $ Meta/cook

    このスクリプトは、 master..seen 間の履歴を検査し、トピックブランチの先端を見つけ、見つかったものを Meta/whats-cooking.txt の現在の内容と比較し、 Meta/whats-cooking.txt を更新します。 ファイルにリストされていないが master..seen にあるトピックは、「New topics」セクションに追加されます。ファイルにリストされ、 master..seen に見つからなくなったトピックは、「Graduated to master」セクションに移動されます。 コミットによって状態が変更されたトピック(たとえば、以前は「seen」のみでしたが、現在は「next」にマージされていますとか)は、変更マーカー << および >> で更新されます。

    << と >> で囲まれた行を探します。 これらは、この統合ラウンドによって置き換えられた古いファイルのコンテンツを保持します。 それらを確認(verify)した後、古い部分を削除します。 各トピックの説明を確認し、必要に応じてその完成度と計画を更新します。 更新された計画を確認するには、以下を実行します

    $ Meta/cook -w

    これは、 "Will merge to next" などの、トピックに付けられたコメントを取得します(サポートされているフレーズの種類については、 Meta/cook を参照してください)。

  • 4つ(5つ)すべての統合ブランチをコンパイル、テスト、およびインストールします。 Meta/Dothem スクリプトは、このステップで役立つでしょう。

  • master ブランチが更新された場合は、ドキュメントをフォーマットします。 Meta/dodoc.sh スクリプトがこのステップに役立つでしょう。

  • 統合ブランチを公共の場所にプッシュします。 Meta/pushall スクリプトがこのステップに役立つでしょう。

Observations

行うべきいくつかの観測。

  • 各トピックは個別にテストされ、他のトピックと一緒に、最初に「seen」、次に「jch」、それから「next」で調理(cooking)されます。 それが成熟するまで、その一部は「master」にマージされません。

  • すでに「next」にあるトピックは、「next」にある間に修正を取得できます。 このようなトピックには、「next」への多くのマージがあります(つまり、 git log --first-parent next は、同じトピックに対して多くの「nextへマージする ai/topic ブランチ」(Merge branch ai/topic to next)を表示します。

  • maint の明白でない修正は、 next で調理され、 master にマージされて、それがOKであることを確認してから、 maint にマージされます。

  • next が空になった場合(つまり、すべてのトピックが安定して master にマージされ、 git diff master next が空の場合)でも、next には、 master には決して存在しない大量のマージコミットがあります。

  • 原則として、 git log --first-parent master..next はマージのみを表示するべきです(実際には、マージではない fixupコミット と revert があります)。

  • next にないトピックブランチの先端近くのコミットは、破棄または置換または書き換えのいいカモ(fair game)です。 next にすでにマージされているコミットはそうではありません。

  • next ブランチにあることは、そのトピックが次の機能リリースに含まれることを保証するものではありません。「master」ブランチにあるのは通常、次の機能リリースに含まれます。

  • 「SQUASH???」修正の性質上、元の作成者が提案された変更に同意する場合は、次のラウンドで適切なパッチにそれらを押しつぶして(squash)もかまいません(提案された変更が十分に小さい場合、作成者は「Helped-by」を気にする必要はありません)。元の作者が提案に同意しない場合は、次のラウンドからそれらを削除することもできますが、作者は議論のどこかで理由を述べることが期待されます。

Appendix

Preparing a "merge-fix"

2つのトピックをマージする際、 字面的には競合しない場合でも、 意味的なレベルで競合が発生することがあります。 典型的な例として、 あるトピックが変数とそのすべての使用箇所をリネームし、 別のトピックがその変数の古い名前で新しい使用箇所を追加する場合があります。 これらの2つのトピックをマージすると、 後者のトピックで新たに追加された変数の参照は、 結果として依然として古い名前を使用することになります。

redo-jch および redo-seen スクリプトで使用される Meta/Reintegrate スクリプトは、この問題を回避するための大雑把ですが使用可能な方法を実装しています。 スクリプトがブランチ$Xをマージするとき、「refs/merge-fix/$X」が存在するかどうかをチェックし、存在する場合、その効果は機械的マージの結果に押しつぶされ(squash)ます。 言い換えると、

$ echo $X | Meta/Reintegrate

これは以下のシーケンスとほぼ同等です:

$ git merge --rerere-autoupdate $X
$ git commit
$ git cherry-pick -n refs/merge-fix/$X
$ git commit --amend

この「prepare a merge-fix」(マージ修正の準備)ステップの目標は、セマンティックの競合を修正するために、機械的なマージの結果に押しつぶす(squash)ことができるコミットを提案することです。

ブランチ「ai/topic」を統合ブランチにマージした結果に、たとえば seen~4 のようなセマンティックの競合があることがわかった後、切り離されたHEAD(detached HEAD)で問題のあるマージをチェックし、作業ツリーを編集してセマンティックの競合を修正し、修正を記録するための別のコミットを行います:

$ git checkout seen~4
$ git show -s --pretty=%s ;# double check
Merge branch 'ai/topic' to seen
$ edit
$ git commit -m 'merge-fix/ai/topic' -a

次に、「refs/merge-fix/ai/topic」を参照して、この結果を示します:

$ git update-ref refs/merge-fix/ai/topic HEAD

それから、Meta/Reintegrate にマージをやり直すように依頼して、結果を再確認(double check)します:

$ git checkout seen~5 ;# the parent of the problem merge
$ echo ai/topic | Meta/Reintegrate
$ git diff seen~4

今回は、refs/merge-fix/ai/topic を準備したため、結果のマージは、セマンティックの競合の修正を含むように調整されているはずです。

注意: これは、競合するブランチがマージされる順序が変更されないことを前提としていることに注意してください。 ai/topic ブランチをマージする理由がこのマージ修正を必要とする場合、統合ブランチに以前にマージされた別のブランチが、ai/topicブランチが作成した基本的な仮定を変更したためです(たとえば、ai/topicブランチは、変数を参照するサイトを追加しましたが、 他のブランチはその変数の名前を変更し、既存の使用サイトを調整したとか)、他のブランチの前に ai/topic ブランチをマージするように redo-jch(またはredo-seen)スクリプトを変更した場合、ai/topicのマージ中に上記のmerge-fixを適用しないで、代わりに他のブランチをマージするときに適用する必要があります。他のブランチに適用するには、修正を移動する必要があります。おそらく以下のようになります:

$ mf=refs/merge-fix
$ git update-ref $mf/$the_other_branch $mf/ai/topic
$ git update-ref -d $mf/ai/topic