セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
- 2.35.1 → 2.50.1 変更なし
-
2.35.0
2022-01-24
- 2.28.1 → 2.34.8 変更なし
-
2.28.0
2020-07-27
- 2.23.1 → 2.27.1 変更なし
-
2.23.0
2019-08-16
- 2.18.1 → 2.22.5 変更なし
-
2.18.0
2018-06-21
- 2.17.0 → 2.17.6 変更なし
-
2.16.6
2019-12-06
- 2.13.7 → 2.15.4 変更なし
-
2.12.5
2017-09-22
- 2.1.4 → 2.11.4 変更なし
-
2.0.5
2014-12-17
説明
このドキュメントでは、git.git
自体で使用されているワークフロー要素の一部を記述し、その動機付けを試みます。関係者の少ない小規模なプロジェクトでは完全なワークフローはほとんど必要ありませんが、多くのアイデアは一般的に適用できます。
手早く参照できるように一連の「ルール」を定式化し、各ルールについて散文で動機付けを試みます。これらのルールを常に文字通りに受け取るのではなく、このマニュアルページよりも自分の行動の正当な理由を重視するべきです。
変更の分離
一般原則として、変更は小さな論理的ステップに分割し、それぞれをコミットするように努めるべきです。それらは一貫性があり、後のコミットから独立して動作し、テストスイートに合格するなどであるべきです。これにより、レビュープロセスがはるかに簡単になり、git-blame[1] や git-bisect[1] などによる後の調査や分析のために履歴がはるかに有用になります。
これを達成するために、最初から作業を小さなステップに分割するように努めてください。複数の大きなコミットを1つにまとめるよりも、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] を使用)する必要があります。これは数回発生しますが、非常に頻繁に行わない限り心配する必要はありません。
トピックブランチ
どんな些細な機能でも実装には複数のパッチが必要であり、そのライフタイム中に追加のバグ修正や改善が行われる可能性があります。
すべてを統合ブランチに直接コミットすると、多くの問題が発生します。悪いコミットは元に戻せないため、一つずつ元に戻す必要があり、混乱した履歴が作成され、一連の変更の一部を元に戻すのを忘れると、さらなるエラーの可能性が生じます。並行作業は変更を混在させ、さらなる混乱を生み出します。
「トピックブランチ」を使用することで、これらの問題は解決されます。名前は非常に分かりやすいですが、上記の「上方へのマージ」ルールに由来する注意点があります。
すべてのトピック(機能、バグ修正など)に対してサイドブランチを作成します。最終的にマージしたい最も古い統合ブランチからそれを分岐させます。
そうすると、多くのことが非常に自然に行えるようになります。
-
機能/バグ修正を統合ブランチに組み込むには、単にマージするだけです。その間にトピックがさらに進化した場合は、再度マージします。(必ずしも最も古い統合ブランチに最初にマージする必要はありません。たとえば、バグ修正を最初に next にマージし、テスト期間を与え、安定していると分かったときに maint にマージすることができます。)
-
トピックの作業を継続するために、別の ブランチから新しい機能が必要であると判断した場合は、別の ブランチを トピック にマージします。(ただし、これを「習慣的に」行わないでください。以下を参照してください。)
-
間違ったブランチから分岐してしまい、それを「過去に戻したい」場合は、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 を使用します。
git
log
master..maint
このコマンドはコミットをリストすべきではありません。もしリストされる場合は、master をチェックアウトし、それに maint をマージしてください。
これで、機能リリースの作成に進むことができます。_master_ の先端にリリースバージョンを示すタグを適用します。
git
tag
-s
-m
"Git
X.Y.Z"
vX.Y.Z
master
新しいタグを公開 Git サーバーにプッシュする必要があります(以下の「分散ワークフロー」を参照)。これにより、プロジェクトを追跡している他のユーザーがタグを利用できるようになります。プッシュにより、リリース tarball のビルドや整形済みドキュメントページの作成など、リリース関連の項目を実行するための post-update フックがトリガーされることもあります。
同様に、メンテナンスリリースの場合、maint はリリースされるコミットを追跡します。したがって、上記の手順で master ではなく maint にタグを付けてプッシュするだけです。
機能リリース後のメンテナンスブランチ管理
機能リリース後、メンテナンスブランチを管理する必要があります。
まず、最近の機能リリース以前に行われた機能リリースのメンテナンス修正をリリースし続けたい場合は、その以前のリリースのコミットを追跡するための別のブランチを作成する必要があります。
これを行うには、現在のメンテナンスブランチを、以前のリリースバージョン番号(例:現在のリリースがX.Y.Zの場合、maint-X.Y.(Z-1))で命名された別のブランチにコピーします。
git
branch
maint-X.Y.
(Z-1
) maint
maint ブランチは、現在のリリースに対するメンテナンス修正を追跡できるように、新しくリリースされたコードにfast-forwardされる必要があります。
-
git
checkout
maint
-
git
merge
--ff-only
master
fast-forward ではないためマージが失敗した場合、maint の一部の修正が機能リリースで漏れていた可能性があります。このような事態は、前のセクションで説明したように、ブランチの内容が検証されていれば発生しません。
機能リリース後のnextおよびseenのブランチ管理
機能リリース後、統合ブランチ 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>
時折、メンテナがダウンストリームから変更をプルしようとしたときにマージの競合が発生することがあります。この場合、ダウンストリームにマージを行って競合を解決するように依頼することができます(おそらく彼らの方が解決方法をよく知っているでしょう)。これは、ダウンストリームがアップストリームからマージ「すべき」まれなケースの1つです。
パッチワークフロー
変更をメールの形式で上流に送信する貢献者である場合は、通常どおりトピックブランチを使用する必要があります(上記参照)。次に、git-format-patch[1] を使用して対応するメールを生成します(手動でフォーマットするよりも、メンテナの作業を楽にするため、強くお勧めします)。
-
git
format-patch
-M
upstream..topic
で整形済みパッチファイルに変換します。 -
git
send-email
--to=
<recipient> <patches>
詳細な使用上の注意については、git-format-patch[1] および git-send-email[1] のマニュアルページを参照してください。
メンテナがあなたのパッチが現在のアップストリームに適用されなくなったと告げた場合、あなたのトピックをリベースする必要があります(マージのformat-patchはできないため、マージは使用できません)。
git
pull
--rebase
<URL> <branch>
これにより、リベース中にコンフリクトを解決できます。おそらく、あなたはメール以外でトピックを公開していないでしょうから、リベースしても問題ありません。
そのようなパッチシリーズを受け取った場合(メンテナとして、またはそれが送られたメーリングリストの読者として)、メールをファイルに保存し、新しいトピックブランチを作成して、git am を使用してコミットをインポートします。
git am < patch
注目すべき機能の1つは、競合が発生した場合に役立つ3方向マージです。git
am
-3
は、パッチに含まれるインデックス情報を使用してマージベースを特定します。その他のオプションについては、git-am[1] を参照してください。
GIT
git[1]スイートの一部