古いブランチのトランクからのバグ修正をマージ


9

私は現在、私の会社でsvnからgitへの切り替えの過程にあります(1年後に、人々を説得するために費やしました!)。

これまでのところ、これですべてが良くなりますが、私たちが現在ワークフローに持っている小さなものの1つで、私には適切な同等のものを見つけることができません。

現在、すべての開発者はマスターで作業しています。四半期ごとに、マスターをXxブランチにブランチします。Xxブランチは後で最新のリリースになります。これは、svnリポジトリが次のようになることを意味します。

  • トランク
    • 3.8
    • 4.1
    • 4.2
    • ...

実際にはタグを使用しません。

時々、発見された緊急のバグ修正があります。

私たちがそれを行う現在の方法は次のとおりです。

  • マスターで修正する
  • SVNは、関連するコミットの範囲を関連するブランチにマージします(おそらく、最新のリリースなど)。

私たちは宇宙産業にいるので、支社は長命であり、顧客のアップグレードプロセスはかなり長いので、これまでのところ、そのように取り組んできました。

さて、gitでどのようにして良い同等物でしょうか?

これまでのところ、マスターから生成されたブランチのバグを修正してから、このブランチをマスターと4.3にマージしました(たとえば)。ことは、ホットフィックスブランチにはマスター履歴が含まれており、マスターと4.3の間のすべてのコミットもマージされるためですが、これは不要です。

これまでに考えたこと:

  • 私は非常に成功したGitワークフローメソッドを見てきましたが、それらの解決策は、リリースブランチのバグ修正して、逆マージするのではなく、マージすることです。これは私たちのケースではうまくいくかもしれませんが、実際にバグを修正する前に、バグを修正したい最も古いブランチをすでに知っている必要があるため、かなり面倒です。
  • もう1つの解決策は、マスターで修正してからコミットを選択することです(今日のsvnマージの場合と同様)。ここでの厄介なことは、この場合、チェリーピックが新しいコミットのように見え、関係が失われるため、マージされたものの履歴がどこで失われるかということです。

それを行うための「良い」方法は何ですか?履歴のコミットを修正するか、チェリーピックを使用して、マージされたものや他の何かを手動で追跡する必要がありますか?

gitでの制作経験がほとんどない場合、私は何かを見逃している可能性があります。

回答:


9

Gitフローは、サポートされているリリースが1つだけであり、masterブランチが常に最新のリリースを指していることを前提としています。複数のリリースを同時にサポートするため、そのワークフローを1:1でコピーすることはできません。NvieのGit Flowは分岐戦略の非常に良い例ですが、ニーズに合わせる必要があります。最も重要なのは、複数のアクティブなリリースブランチがあることです。

バグを特定する場合、影響を受けるすべてのバージョンを特定するためにいくつかのテストを行う必要があります。最初に修正を記述してから、それを修正プログラムとしてリリースブランチにマージするだけでは不十分です。通常、影響を受けるバージョンの継続的な範囲が発生します。非常に古いバージョンにはバグが含まれていない可能性があり、新しいバージョンにはそのバグが誤って修正されている可能性があります。修正後に実際になくなったことを確認できるように、各バージョンのバグを確認する必要があります。バグを自動化されたテストケースとして表現できる場合は、を介して問題のあるコミットを見つけるか、git bisectリリースごとにテストを実行することは非常に簡単です。

for release in 3.8 4.1 4.2
do
  git checkout $release
  if ./testcase >release-$release.log
  then echo "$release ok"
  else echo "$release AFFECTED"
  fi
done

今、あなたはtrunk/に修正を書いていたmaster。バグのある部分がバージョン間で変更されている可能性があるため、これは問題があり、パッチは通常、古いバージョンには適用されません。特に、のコードはmaster、マスターで使用可能な機能に依存している可能性があります。これは、以前のバージョンにはなかった可能性があります。したがって、Gitコミットが変更セットだけでなく履歴全体を参照することは、非常に理にかなっています。マージし直すと、依存するすべての履歴が取り込まれます。

この履歴を使用するcherry-pickrebase無視し、同じチェンジセットを使用して新しい履歴を記録しますが、履歴は異なります。指摘したように、コードベースが分かれている場合、これは機能しません。

「正しい」解決策は、影響を受ける最も古いリリースのホットフィックスとしてフィックスを書き込むことです。次に、最も古いリリースを2番目に古いリリースにマージします。通常、新しいリリースには古いリリースのすべてのコミットが含まれるため、これで問題ありません。状況が変わった場合は、マージの競合を手動で解決できます。その後、完了するまで、各リリースを次の新しいリリースにマージし続けます。これにより、適切な履歴が維持され、多くの不要な作業が回避されますが、いずれにしても費やす必要がある労力のみが必要になります。特に、この段階的なマージにより、現在の開発状態に少しずつ近づくことができます。

図として:

| o normal commit |
| x hotfix        |
| ⇘ merging       |

3.8 --o-----------------x
       \                 ⇘
4.1     o--o--o-----------x'
               \           ⇘
4.2             o--o--o-----x''
                       \     ⇘
develop                 o--o--x'''--o--o

2
完全を期すために、テストが少し間違っていて、バージョン3.7に同じバグがあるとしましょう(たとえば、それは3.7ではエッジケースでのみ発生しますが、3.8 +ではより簡単にテストされたケースで発生します)。修正はこのようにマージされました。その時点でチェリーピックだけにしますか?
イズカタ

2
@Izkataはい、その時点では、何らかの賢明な履歴があるふりをすることはできなくなったので、チェリーピッキングは古いリリースに変更を適用する良い方法です。ただし、これはリリースブランチが分岐しており、新しいリリースには古いリリースのすべてのコミットが含まれていないことを意味します。したがって、変更したリリースから開発ブランチまで、マージチェーンを再度実行する必要があります。ただし、最初のマージでは、新しいリリースに修正をすでに適用しているため、選択した変更を破棄できます。
アモン

@amonに回答していただきありがとうございます。あなたの答えは非常に完全で、私がすでに見ていた方向に進んでいるので、検証を行うのは良いことです。私たちは独自の業界の要件を引き受け、Git Flowアプローチを私たちにより適したものに適応させます。再度、感謝します!
jlengrand
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.