385

当社は現在、単純なトランク/リリース/修正プログラムの分岐モデルを使用しており、どの分岐モデルが会社または開発プロセスに最適かについてアドバイスを求めています.

  1. ワークフロー / 分岐モデル

    以下は、私が見たこの 3 つの主な説明ですが、部分的に互いに矛盾しているか、その後に遭遇した問題を整理するのに十分ではありません (以下で説明します)。したがって、これまでのところ、私たちのチームはデフォルトでそれほど優れたソリューションではありません。あなたは何か良いことをしていますか?

  2. マージとリベース (絡み合った履歴とシーケンシャルな履歴)

    pull --rebaseタスクが完了するまでメインラインへのマージを待つ必要がありますか? 個人的には、タスクがどのベースで開始および終了されたかを視覚的に示すことができるので、マージを好みmerge --no-ffます。ただし、他の欠点があります。また、多くの人は、マージの有用な特性、つまり交換可能ではないことに気づいていません(トピック ブランチを master にマージすることは、master をトピック ブランチにマージすることを意味するわけではありません)。

  3. 自然なワークフローを探している

    私たちの手順が単純なルールで特定の状況を捉えていないために、間違いが起こることがあります。たとえば、以前のリリースに必要な修正はもちろん、必要なすべてのブランチにアップストリームをマージできるように、十分にダウンストリームに基づいている必要があります (これらの用語の使用法は十分に明確ですか?)。しかし、開発者がそれをさらに下流に配置する必要があることに気付く前に、修正がマスターに組み込まれることがあり、それが既にプッシュされている場合 (さらに悪いことに、マージまたはそれに基づく何か)、残りのオプションはチェリーピッキングです。それに伴う危険。そのような単純なルールは何を使用しますか?また、これには、他のトピック ブランチを必然的に除外する 1 つのトピック ブランチのぎこちなさが含まれます (それらが共通のベースラインから分岐していると仮定します)。開発者は、書いたばかりのコードがもうそこにないような気がして、別の機能を開始するために機能を終了したくありません。

  4. (cherry-pick による) マージ競合の作成を回避するにはどうすればよいですか?

    マージ競合を作成する確実な方法のように見えるのは、ブランチ間でチェリーピックすることです。それらは二度とマージできませんか? どちらかのブランチで同じコミットを元に戻す (これを行う方法は?) を適用すると、この状況が解決する可能性がありますか? これが、私が大部分のマージ ベースのワークフローを推奨しない理由の 1 つです。

  5. トピックの枝に分解する方法は?

    トピック ブランチから完成した統合を組み立てることは素晴らしいことだと認識していますが、多くの場合、開発者による作業は明確に定義されておらず (「突っついている」だけの場合もあります)、一部のコードが既に「その他」のトピックに含まれている場合は、上記の質問によると、そこから再び持ち出すことはできませんか? トピックブランチの定義/承認/卒業/リリースにどのように取り組んでいますか?

  6. もちろん、コードのレビューや卒業などの適切な手順は素晴らしいものです。

    しかし、これを管理するのに十分なほど複雑にならないようにすることはできません - 何か提案はありますか? 統合ブランチ、イラスト?

以下は、関連する質問のリストです。

また、Plastic SCM がタスク駆動型開発について書いていることも確認してください。Plastic を選択しない場合は、nvie の分岐モデルサポート スクリプトを調べてください。

4

4 に答える 4

93

DVCS の新しい開発者が認識しなければならない最も厄介な機能は、公開プロセスに関するものです。

  • 必要なリモートリポジトリをインポート(フェッチ/プル)できます
  • 任意の (裸の) リポジトリに公開 (プッシュ) できます

それから、いくつかのルールを尊重して、質問を簡単にすることができます。

今:

ワークフロー/分岐モデル:

各ワークフローはリリース管理プロセスをサポートするためにあり、プロジェクトごとに調整されています。
あなたが言及したワークフローに追加できるのは、各開発者は機能ブランチを作成するのではなく、「現在の開発」ブランチのみを作成する必要があるということです.機能、いくつか (機能が複雑すぎるため)、なし (リリースに間に合わないため)、別の機能 (元の機能が「モーフィング」されたため)、...

「インテグレーター」のみが「中央」レポに公式の機能ブランチを確立する必要があります。これにより、開発者がフェッチして、その機能に適合する作業の一部をリベース/マージできます。

マージとリベース (絡み合った履歴とシーケンシャルな履歴) :

あなたが言及した私の答えが好きです(「社内開発のためのgit使用のワークフローの説明」)

自然なワークフローを探しています:

修正の場合、各修正をバグ追跡からのチケットに関連付けるのに役立ちます。これにより、開発者は、そのような変更をコミットする必要がある場所 (つまり、どのブランチ、つまり「修正用」の専用ブランチ) を思い出すことができます。
次に、フックは、検証されていないバグ修正またはプッシュしてはならないブランチからのプッシュから中央リポジトリを保護するのに役立ちます。(ここには特定の解決策はありません。これらすべてを環境に適応させる必要があります)

(cherry-pick による) マージ競合の作成を回避するにはどうすればよいですか?

Jakub Narębskiの回答で述べられているように、チェリー ピッキングは、それが必要なまれな状況のために予約する必要があります。
もしあなたのセットアップが多くのチェリーピッキングを含んでいるなら (つまり、「それはまれではない」)、何かがおかしくなっています。

元に戻すときに同じコミットを適用しますか (これを行う方法は?)

git revertそれを処理する必要がありますが、それは理想的ではありません。

トピックの枝に分解する方法は?

ブランチがまだどこにもプッシュされていない限り、開発者はコミットの履歴を次のように再編成する必要があります (開発がより決定的で安定した形になるのを最終的に確認したら)。

  • 必要に応じていくつかのブランチ (明確に識別された特徴によるもの)
  • 1 つのブランチ内の一貫した一連のコミット ( Git チェックインのトリミングを参照)

コードレビューや卒業などの適切な手順は?

統合ブランチ (専用の統合内) リポジトリは、開発者が次のことを行うのに役立ちます。

  • そのリモート統合ブランチの上に自分の開発をリベースします (pull --rebase)
  • 局所的に解決する
  • 開発をそのレポにプッシュする
  • 混乱を招かないインテグレーターに確認してください;)
于 2010-04-12T12:01:40.937 に答える
22

git について最も誤解されていることの 1 つは、その分散型の性質だと思います (間違っているかもしれません)。これにより、必要に応じてSVNの動作を模倣することはできますが、作業方法で転覆と言うのは非常に異なります。問題は、ほとんどすべてのワークフローで実行できることです。これは素晴らしいことですが、誤解を招く可能性もあります。

私がカーネル開発について正しく理解していれば (ここではそれに焦点を当てます)、誰もがカーネルを開発するための独自の git リポジトリを持っています。Torvalds が管理する linux-2.6.git という 1 つのリポジトリがあり、リリース リポジトリとして機能します。「リリース」ブランチに対する機能の開発を開始したい場合は、ここからクローンします。

他のリポジトリは、いくつかの開発を行います。アイデアは、linux-2.6 からクローンを作成し、「新しい」機能が機能するようになるまで、何度でも分岐することです。次に、これが準備できたら、信頼できると見なされた人が利用できるようにすることができます。信頼できる人は、このブランチをあなたのリポジトリから自分のリポジトリにプルし、メインストリームにマージします。Linux カーネルでは、これはいくつかのレベル (信頼できる副官) で発生し、linux-2.6.git に到達すると「カーネル」になります。

さて、ここがややこしいところです。ブランチ名はリポジトリ間で一貫している必要はまったくありません。したがって、 というリポジトリのブランチで、 のマスターgit pull origin master:vanilla-codeからブランチを取得できます。何が起こっているかを知っていれば、それは実際には問題ではありません.SVNのような複数のコンピューターで共有されるだけでなく、すべてのリポジトリが互いにピアであるという意味で分散されています.originvanilla-code

したがって、これらすべてを念頭に置いて:

  1. 分岐をどのように行うかは、各プログラマ次第だと思います。必要なのは、リリースなどを管理するための中央リポジトリだけです。トランクはhead. リリースはタグまたはブランチである可能性があり、ホットフィックスはおそらくそれ自体がブランチです。実際、パッチを適用し続けることができるように、リリースをブランチとして行う可能性があります。
  2. リベースではなくマージします。たとえば、リポジトリを取得してクローンを作成し、ブランチを作成して開発を行ってから、リポジトリからプルするorigin必要がある場合は、リポジトリでおそらく別のブランチを作成し、最新のものをマージして、master他のyourbranch誰かが最小限の労力で変更をプルできるようにします可能。私の経験では、本当にリベースする必要はほとんどありません。
  3. Git の仕組みと何ができるかを理解することだと思います。しばらく時間がかかり、十分なコミュニケーションが必要です。他の開発者と git を使い始めてから、何が起こっているのかを本当に理解し始めました。今でも、よくわからないことがあります。
  4. マージ競合は便利です。すべてが機能することを望んでいることはわかっていますが、実際にはコードが変更されており、結果をマージして機能するものにする必要があります。マージの競合は、実際には単なるプログラミングです。それらについて何をすべきかについての簡単な説明を見つけたことがありませgit add .git commit
  5. しかし、それは合っています。前述したように、各ユーザーの git リポジトリは独自のものであり、ブランチ名は同じである必要はありません。たとえば、ステージング リポジトリがある場合、ネーミング スキーマを適用できますが、開発者ごとに行う必要はなく、リリース リポジトリでのみ行う必要があります。
  6. これがマージ段階です。コードがレビュー/品質テストに合格すると見なされる場合にのみ、リリース ブランチなどにマージします。

それが役立つことを願っています。非常によく似た説明を投稿したばかりの VonC に気付きました... 十分に速く入力できません!

これはコメントから OP に関連しているように思われるため、商用設定で git を使用する方法についてさらにいくつかの考えを編集します。

  • リリース リポジトリ (私たちはこれを と呼びます) にはproduct.git、実際に製品自体の管理を担当する多くのシニア プログラマーや技術者がアクセスできます。彼らは、OSS におけるメンテナーの役割に似ています。
  • これらのプログラマーは、おそらく一部は新しいバージョンの開発もリードしているため、自分自身でコーディングしてさまざまなリポジトリを維持している可能性もあります。彼らは本当に新しい機能のステージング リポジトリを管理し、独自のリポジトリを持っている場合もあります。
  • その下には、個々のビットの開発を担当するプログラマーがいます。たとえば、誰かが UI 作業を担当している場合があります。そのため、UI.git リポジトリを管理します。
  • その下には、日々の仕事として機能を開発している実際のプログラマーがいます。

それでどうなるの?ええと、誰もが「アップストリーム」ソース、つまりリリース リポジトリ (おそらく前日の開発からの最新の資料も含まれる) から毎日の開始時にプルします。誰もがこれを直接行います。これは、おそらく「マスター」と呼ばれる、またはおそらく「最新」と呼ばれるリポジトリのブランチに移動します。その後、プログラマーはいくつかの作業を行います。この作業は、彼らが確信していないものかもしれないので、ブランチを作成して作業を行います。うまくいかない場合は、ブランチを削除して戻ることができます。その場合、現在取り組んでいるメイン ブランチにマージする必要があります。これlatest-uiは作業中の UI プログラマーであるとします。git checkout latest-uigit merge abc-ui-mywhizzynewfeature. 次に、テクニカル リード (UI リード) に、このようなタスクを完了したことを伝えます。したがって、UI リードはそうしgit pull user-repo lastest-ui:lastest-ui-suchafeature-abcます。次に、UI リーダーはそのブランチでそれを見て、実際、それはとても良いことだと言います。これを にマージしますui-latest。その後、彼は自分の下にいるすべての人に、ブランチまたは彼らが付けた名前で彼からプルするように指示する可能性がui-latestあり、その機能は開発者によって調査されます。チームが満足している場合、UI リードはテスト リードに変更をプルしてマージするように依頼する場合があります。これは、それをテストしてバグレポートなどを提出するすべての人 (変更の下流) に伝播します。最後に、機能がテストなどに合格した場合、トップの技術リーダーの 1 人がそれをプログラムの現在の作業コピーにマージする可能性があります。その後、すべての変更が伝播されます。等々。

これは「伝統的な」作業方法ではなく、SVN/CVS のような「階層的」ではなく「ピア主導」になるように設計されています。本質的に、全員がコミット アクセス権を持っていますが、ローカルでのみアクセスできます。階層を使用できるようにするのは、リポジトリへのアクセスと、リリース リポジトリとして指定するリポジトリです。

于 2010-04-12T12:07:31.327 に答える
10

私が使用して良い結果が得られたモデルは次のとおりです。

誰もがプッシュおよびプルする「祝福された」リポジトリ、基本的にはクライアント/サーバートポロジ。

マスターブランチがないため、開発者はコードを「メインライン」にプッシュできません。

すべての開発はトピックブランチで行われます。誰が責任を負っているのかを簡単に検出できるように、名前空間に名前空間を付けました:jn/newFeatureまたはjn/issue-1234

ホワイトボードには、ブランチとかんばん/スクラムカードの間にほぼ1対1のマッピングもあります。

ブランチを解放するために、それは祝福されたレポにプッシュされ、かんばんカードはレビューの準備ができた状態に移動されます。

次に、そのブランチがレビューによって承認された場合、それはリリースの候補になります。

承認されたブランチのセットがマージされ、バージョン番号でタグ付けされると、リリースが発生します。

新しいタグを祝福されたリポジトリにプッシュすることにより、新しい機能の新しい可能なベースがあります。

マージの競合を回避するために、開発者は、リリースされていないブランチを最新のリリースタグに更新(マージ)するようにお願いします。

于 2011-10-11T11:28:30.580 に答える
2

個人的には、master ブランチにはリリース可能なコードだけを残すようにしています。

新しい機能やバグ修正に取り組むときは、ブランチで行います。また、ブランチで単体テストを行います。すべてがうまくいった場合にのみ、マスターにマージ/リベースします。

私は、次のような一般的なブランチの命名規則も使用しようとしています。

  • バグ修正/recursive_loop
  • バグ修正/sql_timeout
  • 機能/new_layout
  • 機能/enhanced_search
于 2012-12-20T22:16:13.677 に答える