web-dev-qa-db-ja.com

どのGit分岐モデルが機能しますか?

当社では現在、単純なtrunk/release/hotfixes分岐モデルを使用しており、企業または開発プロセスに最適な分岐モデルについてアドバイスを求めています。

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

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

  2. マージとリベース(もつれと順次の履歴)

    pull --rebaseを1つ、またはタスクが完了するまでメインラインにマージして待つ必要がありますか?個人的には、マージの傾向があります。これにより、タスクの開始と終了の視覚的な図が保持されるため、この目的のためにmerge --no-ffを好むことさえあります。ただし、他の欠点もあります。また、多くの人はマージの有用な特性を認識していません-それは commutative ではありません(トピックブランチをマスターにマージすることは、マスターをトピックブランチにマージすることを意味しません)。

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

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

  4. マージ競合の発生を回避する方法(チェリーピックによる)?

    マージの競合を作成する確実な方法のように思えるのは、ブランチ間をチェリーピックすることです。ブランチを再びマージすることはできませんか?どちらかのブランチで同じコミットを元に戻す(これを行う方法?)と、この状況が解決する可能性がありますか?これは、主にマージベースのワークフローをプッシュすることを敢えてしない理由の1つです。

  5. トピックブランチに分解する方法は?

    トピックブランチから完成した統合を組み立てるのは素晴らしいことですが、多くの場合、開発者による作業は明確に定義されていません(「突っ回る」などの単純な場合もあります)。上記の質問によると、再びそこから取り出すことはできませんか?トピックブランチの定義/承認/卒業/リリースをどのように行いますか?

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

    しかし、これを管理するのに十分なほど絡み合った状態を保つことはできません-提案はありますか?統合ブランチ、イラスト?

以下に関連する質問のリストを示します。

また、Plastic SCMの記述内容 タスク駆動型開発 を確認してください。Plasticが選択されない場合は、 nvieの分岐モデル および彼の サポートスクリプト を調べてください。

363
HiQ CJ

DVCSの新しい開発者が実現する必要がある最も厄介な機能は、 公開プロセス についてです。

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

それから、あなたはあなたの質問をより簡単にするためにいくつかの規則を尊重することができます:

今:

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

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

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

マージvsリベース(もつれvsシーケンシャル履歴)

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

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

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

マージ競合の発生を回避する方法(チェリーピックによる)?

JakubNarębski in his answer で述べられているように、チェリーピッキングは必要なまれな状況のために予約すべきです。
多くのチェリーピッキング(つまり、「珍しいことではない」)がセットアップに含まれている場合、何かがオフになっています。

復帰時に同じコミットを適用しますか(これを行う方法は?)

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

トピックブランチに分解する方法は?

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

  • 必要に応じて複数のブランチ(明確に識別された機能ごとに1つ)
  • 1つのブランチ内の一貫したコミットセット( [Gitチェックインのトリミング )を参照)

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

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

  • そのリモート統合ブランチの上に開発をリベースします(pull --rebase)
  • 局所的に解決する
  • 開発をそのレポにプッシュする
  • 混乱をもたらさないインテグレーターに確認してください;)
89
VonC

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

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

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

ここで混乱するところです。ブランチ名は、リポジトリ全体で一貫している必要はありません。したがって、git pull Origin master:Vanilla-codeを使用して、リポジトリ内のVanilla-codeというブランチにあるOriginのマスターからブランチを取得できます。何が起こっているかを知っていれば、それは本当に問題ではありません。すべてのリポジトリが相互にピアであり、SVNのような複数のコンピュータ間で共有されるだけではないという意味で配布されます。

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

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

それがお役に立てば幸いです。 VonCが非常によく似た説明を投稿したばかりであることに気づきました...十分な速さで入力できません!

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

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

それでどうなりますか?さて、誰もが毎日の始めに「上流」のソース、つまりリリースリポジトリ(おそらく前日の開発からの最新の資料を含むでしょう)からプルします。誰もが直接これを行います。これは、リポジトリのブランチ(おそらく「マスター」と呼ばれるか、私が「最新」と呼ばれる場合)に移動します。その後、プログラマーはいくつかの作業を行います。この仕事は彼らが確信していないものかもしれないので、彼らはブランチを作り、仕事をします。動作しない場合は、ブランチを削除して戻ることができます。もしそうなら、彼らは現在作業中のメインブランチにマージする必要があります。これはlatest-uiに取り組んでいるUIプログラマーだと言うので、彼はgit checkout latest-uiに続いてgit merge abc-ui-mywhizzynewfeatureを実行します。その後、彼は技術リーダー(UIリーダー)に、このようなタスクを完了しました。したがって、UIリードはgit pull user-repo lastest-ui:lastest-ui-suchafeature-abcを実行します。 UIリードは、そのブランチでそれを調べ、実際、それは非常に良いと言います。それをui-latestにマージします。その後、彼は下のすべての人にui-latestブランチまたは彼らが付けた名前を彼から引き出すように指示するかもしれません。そのため、開発者はこの機能を検討します。チームが満足している場合、UIリーダーはテストリーダーに依頼して、変更をマージするよう依頼する場合があります。これは、テスト(バグの報告など)を送信するすべての人(変更の下流)に伝達されます。その後、すべての変更が再び伝播されます。等々。

これは「伝統的な」作業方法ではなく、SVN/CVSのような「階層」ではなく「ピア駆動」になるように設計されています。本質的に、誰もがコミットアクセスを持ちますが、ローカルのみです。階層へのアクセスを可能にするのは、リポジトリへのアクセスと、どのリポジトリをリリースリポジトリとして指定するかです。

21
user257111

良い結果で使用したモデルは次のとおりです。

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

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

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

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

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

その後、レビューによってブランチが受け入れられた場合、リリースの候補になります。

リリースは、受け入れられたブランチのセットがマージされ、バージョン番号でタグ付けされたときに発生します。

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

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

9
John Nilsson

個人的に、私はmasterブランチでリリース可能なコードのみを保持しようとします。

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

私は、次のような一般的なブランチ命名規則も試してみます:

  • バグ修正/再帰的ループ
  • バグ修正/ sql_timeout
  • feature/new_layout
  • feature/enhanced_search
2
xero