日本語 ▾ トピック ▾ 最新バージョン ▾ gitworkflows は 2.35.0 で最終更新されました

名称

gitworkflows - Git で推奨されるワークフローの概要

書式

git *

説明

このドキュメントは、git.git 自体で使用されているワークフローの要素を記述し、その理由を説明することを試みます。多くのアイデアは一般的に適用できますが、関係者の少ない小規模なプロジェクトでは、完全なワークフローが要求されることは稀です。

ここでは、素早い参照のために一連のルールを策定し、本文ではそれぞれの理由を説明します。常に文字通りに受け取る必要はありません。このようなマニュアルページよりも、あなたの行動の正当な理由をより高く評価すべきです。

変更の分離

一般原則として、変更を小さな論理的なステップに分割し、それぞれをコミットするようにしてください。それらは一貫性があり、その後のコミットから独立して動作し、テストスイートに合格するなどであるべきです。これにより、レビュープロセスがはるかに容易になり、git-blame[1]git-bisect[1] などによるその後の検査や分析に履歴がはるかに役立つようになります。

これを達成するために、最初から作業を小さなステップに分割するようにしてください。大きなコミットをいくつか分割するよりも、いくつかのコミットをまとめる方が常に簡単です。途中で小さすぎたり不完全なステップを作成することを恐れないでください。公開する前に、いつでも後で git rebase --interactive でコミットを編集できます。他のコミットされていない変更とは独立してテストスイートを実行するために git stash push --keep-index を使用できます。git-stash[1] の EXAMPLES セクションを参照してください。

ブランチの管理

あるブランチから別のブランチに変更を含めるために使用できる主要なツールは2つあります。git-merge[1]git-cherry-pick[1] です。

マージには多くの利点があるため、マージのみでできるだけ多くの問題を解決しようとします。チェリーピックは依然として時々役立ちます。例については、以下の「上位ブランチへのマージ」を参照してください。

最も重要なのは、マージがブランチレベルで機能するのに対し、チェリーピックがコミットレベルで機能することです。これは、マージが1、10、または1000コミットからの変更を同様に簡単に引き継ぐことができることを意味し、ひいては、多数の貢献者(および貢献)に対してワークフローがはるかに適切にスケーリングすることを意味します。マージコミットは、そのすべての親からのすべての変更が現在含まれていることの「約束」であるため、マージは理解しやすいでもあります。

もちろんトレードオフもあります。マージにはより注意深いブランチ管理が必要です。以下のサブセクションでは、重要な点について説明します。

段階的導入

特定の機能が実験段階から安定段階へと移行するにつれて、ソフトウェアの対応するブランチ間を「卒業」します。git.git は以下の統合ブランチを使用します

  • maint は、次の「メンテナンスリリース」、つまり最後にリリースされた安定版の更新に含めるべきコミットを追跡します。

  • master は、次のリリースに含めるべきコミットを追跡します。

  • next は、master 用の安定性をテスト中のトピックのためのテストブランチとして意図されています。

わずかに異なる方法で使用される4番目の公式ブランチがあります

  • seen (メンテナによって確認されたパッチ) は、まだ取り込みの準備ができていないもの(以下の「統合ブランチ」を参照)のための統合ブランチです。

4つのブランチはそれぞれ、通常、その上位のブランチの直接の子孫です。

概念的には、機能は不安定なブランチ(通常は next または seen)で導入され、十分安定していると見なされると、次のリリースに向けて master に「卒業」します。

上位ブランチへのマージ

上記で議論した「下位ブランチへの卒業」は、実際に下位ブランチへマージすることで行うことはできません。なぜなら、それでは不安定なブランチのすべての変更が安定版にマージされてしまうからです。したがって、以下のようになります

ルール:上位ブランチへマージする

常に、修正が必要な最も古いサポートされているブランチに修正をコミットしてください。その後、(定期的に)統合ブランチを互いの上位ブランチにマージします。

これにより、修正のフローが非常に制御されます。たとえば、master に適用した修正が maint でも必要であることがわかった場合、それを下位ブランチへチェリーピック(git-cherry-pick[1] を使用して)する必要があります。これは数回発生しますが、非常に頻繁に行わない限り心配することはありません。

トピックブランチ

些細ではない機能は、実装にいくつかのパッチを必要とし、そのライフサイクル中にさらなるバグ修正や改善が行われる可能性があります。

統合ブランチにすべてを直接コミットすると、多くの問題が生じます。問題のあるコミットは元に戻すことができないため、1つずつリバートする必要があります。これは混乱した履歴を作成し、変更グループの一部をリバートし忘れた場合にさらなるエラーの可能性を生み出します。並行して作業すると変更が混ざり合い、さらなる混乱を引き起こします。

「トピックブランチ」の使用はこれらの問題を解決します。この名前は非常に分かりやすいですが、上記の「上位ブランチへのマージ」ルールから来る注意点があります

ルール:トピックブランチ

すべてのトピック(機能、バグ修正など)に対してサイドブランチを作成します。最終的にマージしたい最も古い統合ブランチからそれをフォークします。

多くのことを非常に自然に行うことができます

  • 機能/バグ修正を統合ブランチに取り込むには、単にマージします。その間にトピックがさらに進化した場合は、再度マージします。(必ずしも最初に最も古い統合ブランチにマージする必要はありません。例えば、まずバグ修正を next にマージし、テスト期間を設け、安定していると分かったら maint にマージすることができます。)

  • トピックでの作業を続行するために、ブランチ other から新しい機能が必要になった場合は、othertopic にマージします。(ただし、「習慣的に」これを行うべきではありません。以下を参照してください。)

  • 間違ったブランチからフォークしてしまい、「時間を巻き戻したい」場合は、git-rebase[1] を使用してください。

最後の点が他の2点と矛盾することに注意してください。つまり、すでに他の場所にマージされたトピックはリベースすべきではありません。git-rebase[1] の「RECOVERING FROM UPSTREAM REBASE」セクションを参照してください。

「習慣的に」(実際的な理由もなく定期的に)統合ブランチを自分のトピックにマージすること、ひいては定期的にアップストリームの何かをダウンストリームの何かにマージすることは、推奨されません。

ルール:明確な時点でのみダウンストリームにマージする

正当な理由がない限りダウンストリームにマージしないでください。例えば、アップストリームのAPI変更があなたのブランチに影響する場合、あなたのブランチがアップストリームにクリーンにマージできなくなった場合などです。

そうでなければ、マージされたトピックは突然、単一の(十分に分離された)変更以上のものを含むことになります。結果として生じる多くの小さなマージは、履歴をひどく乱雑にします。後でファイルの履歴を調査する人は、そのマージが開発中のトピックに影響を与えたかどうかを調べなければなりません。アップストリームが意図せず「より安定した」ブランチにマージされることさえありえます。その他諸々。

使い捨て統合

前の段落に従った場合、現在多くの小さなトピックブランチがあり、それらがどのように相互作用するのか時々疑問に思うでしょう。もしかしたら、それらをマージした結果が機能しないかもしれません?しかし、一方で、そのようなマージは簡単には元に戻せないので、どこか「安定した」場所にマージすることは避けたいです。

もちろん、解決策は元に戻せるマージを行うことです。つまり、使い捨てブランチにマージするのです。

ルール:使い捨て統合ブランチ

複数のトピックの相互作用をテストするには、それらを使い捨てブランチにマージします。そのようなブランチを基盤として作業を絶対に行ってはなりません!

このブランチがテスト後すぐに削除されることを(非常に)明確にすれば、このブランチを公開することもできます。例えば、テスターにそれを使って作業する機会を与えたり、他の開発者に進行中の作業が互換性があるかどうかを確認する機会を与えたりするためです。git.git には、seen と呼ばれるそのような公式の使い捨て統合ブランチがあります。

リリース用ブランチ管理

上記で議論したマージアプローチを使用していると仮定すると、プロジェクトをリリースする際に、追加のブランチ管理作業を行う必要があります。

機能リリースは master ブランチから作成されます。なぜなら、master は次の機能リリースに含まれるべきコミットを追跡しているからです。

master ブランチは maint のスーパーセットであるべきです。この条件が満たされない場合、maint には master に含まれていないコミットが含まれていることになります。したがって、それらのコミットで表される修正は、機能リリースには含まれません。

master が実際に maint のスーパーセットであることを検証するには、git log を使用します。

手順:mastermaint のスーパーセットであることを確認する

git log master..maint

このコマンドはコミットをリストアップすべきではありません。そうでない場合は、master をチェックアウトし、maint をそれにマージしてください。

これで機能リリースの作成に進むことができます。master の先端にリリースバージョンを示すタグを適用します。

手順:リリースにタグを付ける

git tag -s -m "Git X.Y.Z" vX.Y.Z master

新しいタグを公開Gitサーバーにプッシュする必要があります(以下の「分散ワークフロー」を参照)。これにより、あなたのプロジェクトを追跡している他の人々にタグが利用可能になります。このプッシュは、リリースtarボールの構築や整形済みドキュメントページの作成など、リリース関連の項目を実行するためのpost-updateフックをトリガーすることもあります。

同様に、メンテナンスリリースの場合、maint がリリースされるコミットを追跡しています。したがって、上記の手順では、master ではなく maint にタグを付けてプッシュするだけです。

機能リリース後のメンテナンスブランチ管理

機能リリース後、メンテナンスブランチを管理する必要があります。

まず、最近の機能リリース以前に行われた機能リリースのメンテナンス修正を引き続きリリースしたい場合は、その以前のリリース用のコミットを追跡するための別のブランチを作成する必要があります。

これを行うには、現在のメンテナンスブランチを、以前のリリースバージョン番号(例:X.Y.Zが現在のリリースである場合、maint-X.Y.(Z-1))で名前を付けた別のブランチにコピーします。

手順:maint をコピーする

git branch maint-X.Y.(Z-1) maint

maint ブランチは、現在のリリースに対するメンテナンス修正を追跡できるように、新しくリリースされたコードにファストフォワードされる必要があります。

手順:maint を新しいリリースに更新する
  • git checkout maint

  • git merge --ff-only master

マージがファストフォワードではないために失敗した場合、maint 上のいくつかの修正が機能リリースで漏れていた可能性があります。前のセクションで説明したようにブランチの内容が検証されていれば、これは発生しません。

機能リリース後のnextとseenブランチ管理

機能リリース後、統合ブランチ next は、オプションで巻き戻され、next 上に残っているトピックを使用して master の先端から再構築される場合があります。

手順:next を巻き戻して再構築する
  • git switch -C next master

  • git merge ai/topic_in_next1

  • git merge ai/topic_in_next2

  • …​

これを行う利点は、next の履歴がクリーンになることです。例えば、next にマージされた一部のトピックは、当初は有望に見えたものの、後に望ましくない、または時期尚早であることが判明したかもしれません。そのような場合、そのトピックは next からリバートされますが、一度マージされてリバートされたという事実は履歴に残ります。next を再作成することで、そのようなトピックの別の「転生」にクリーンな状態から再試行する機会を与え、機能リリースはそうするのに履歴上良い節目となります。

これを行った場合、next が巻き戻され、再構築されたことを示す公開アナウンスを行うべきです。

seen も同様に巻き戻しと再構築のプロセスに従うことができます。seen は上記のように使い捨てブランチであるため、公開アナウンスは不要です。

分散ワークフロー

最後のセクションを読めば、トピックの管理方法が分かるはずです。一般的に、プロジェクトで作業する唯一の人物ではないため、作業を共有する必要があります。

大まかに言うと、重要なワークフローはマージとパッチの2つです。重要な違いは、マージワークフローはマージを含む完全な履歴を伝播できるのに対し、パッチはできない点です。両方のワークフローを並行して使用できます。git.git では、サブシステムメンテナのみがマージワークフローを使用し、他の全員はパッチを送信します。

メンテナは、「Signed-off-by」要件など、取り込みのために提出されるすべてのコミット/パッチが従わなければならない制限を課す場合があることに注意してください。詳細については、プロジェクトのドキュメントを参照してください。

マージワークフロー

マージワークフローは、アップストリームとダウンストリーム間でブランチをコピーすることで機能します。アップストリームは貢献を公式履歴にマージでき、ダウンストリームは公式履歴に基づいて作業を行います。

これには主に3つのツールが使用できます

  • git-push[1] はあなたのブランチをリモートリポジトリ、通常は関係者全員が読み取れるリポジトリにコピーします。

  • git-fetch[1] はリモートブランチをあなたのリポジトリにコピーします。

  • git-pull[1] はフェッチとマージを一度に行います。

最後の点に注意してください。リモートブランチを実際にマージしたい場合を除き、git pull を使用しないでください。

変更を公開するのは簡単です

手順:プッシュ/プル:ブランチ/トピックの公開

git push <remote> <branch> を実行し、どこからフェッチできるかを全員に伝えます。

メールなどの他の手段で人々に伝える必要があります。(Gitは、このタスクを簡素化するために、整形済みのプルリクエストをアップストリームのメンテナに送信するための git-request-pull[1] を提供しています。)

統合ブランチの最新コピーを取得したいだけであれば、最新の状態を維持するのも簡単です。

手順:プッシュ/プル:最新の状態を維持する

git fetch <remote> または git remote update を使用して、最新の状態を維持します。

その後、先に説明したように、安定したリモートからトピックブランチをフォークするだけです。

メンテナで、他の人のトピックブランチを統合ブランチにマージしたい場合、通常、メールでそのためのリクエストが送られてきます。そのようなリクエストは次のようになります。

Please pull from
    <URL> <branch>

その場合、git pull はフェッチとマージを一度に実行できます。以下の通りです。

手順:プッシュ/プル:リモートトピックのマージ

git pull <URL> <branch>

時折、メンテナがダウンストリームから変更をプルしようとすると、マージコンフリクトが発生することがあります。この場合、メンテナはダウンストリームにマージとコンフリクトの解決を依頼できます(おそらく彼らの方が解決方法をよく知っているでしょう)。これは、ダウンストリームがアップストリームからマージすべき稀なケースの一つです。

パッチワークフロー

メールの形式で変更をアップストリームに送信する貢献者である場合、通常通りトピックブランチを使用すべきです(上記を参照)。その後、対応するメールを生成するために git-format-patch[1] を使用してください(メンテナの作業を容易にするため、手動でのフォーマットよりも強く推奨されます)。

手順:format-patch/am:ブランチ/トピックの公開
  • git format-patch -M upstream..topic を実行して、整形済みパッチファイルに変換します。

  • git send-email --to=<recipient> <patches>

詳細な使用方法については、git-format-patch[1] および git-send-email[1] のマニュアルページを参照してください。

メンテナからパッチが現在のアップストリームに適用できなくなったと伝えられた場合、トピックをリベースする必要があります(マージは、マージをformat-patchできないため使用できません)。

手順:format-patch/am:トピックを最新に保つ

git pull --rebase <URL> <branch>

その後、リベース中にコンフリクトを修正できます。おそらく、あなたはメール以外でトピックを公開していないため、それをリベースすることは問題ありません。

そのようなパッチシリーズを受け取った場合(メンテナとして、またはそれが送信されたメーリングリストの読者として)、メールをファイルに保存し、新しいトピックブランチを作成し、git am を使用してコミットをインポートします。

手順:format-patch/am:パッチのインポート

git am < patch

注目すべき機能の一つは、コンフリクトが発生した場合に役立つスリーウェイマージです。git am -3 は、パッチに含まれるインデックス情報を使用してマージベースを特定します。その他のオプションについては、git-am[1] を参照してください。

GIT

git[1] スイートの一部

scroll-to-top