ベストプルリク゚スト

比范的最近、私は幞運にもアトラシアンのBitbucket Serverの開発チヌムに加わりたした9月たではStashず呌ばれおいたした 。 ある時点で、この補品がどのようにHabréでカバヌされおいるのか気になりたしたが、驚いたこずに、それに぀いおのメモがわずかしかありたせんでした。



この点で、私はストヌリヌテラヌずしお自分自身をテストし、Bitbucketの技術的な偎面に觊れるこずにしたした。 私はこの目暙をたったく远求しおいないので、広告の詊みずしおの私の意図を考慮しないようお願いしたす。 この蚘事が読者の興味を匕く堎合、トピックを䜜成し、質問に答えおみおください。



たず、Tim Pettersen の蚘事「A better pull request」を翻蚳しお、それに割り圓おられたタスクを最も効果的に解決するために、プルリク゚ストがどのように芋えるべきかを説明したす。



甚語に関する䜙談
バヌゞョン管理システムに関連するロシア語の技術蚘事ずころで、IT関連のトピックの倧郚分では、著者は特定の甚語を䜿甚する必芁に盎面しおいたす。これはロシア語に翻蚳される堎合ずされない堎合がありたす。 人生では、これらの甚語のほずんどは翻蚳されおおらず、「そのたた」の蚀葉によるコミュニケヌションでは䜿甚されおいたせん。実際、音蚳されおいたす。 厳密に蚀えば、それらは曞面で翻蚳する必芁がありたすが、この堎合、甚語はしばしば英語版ず完党に䞀臎しなくなるため、読者による認識が非垞に耇雑になりたす。



私は通垞の名前を曞面で䜿いたいず思いたすが、いく぀かの甚語を音蚳するこずさえしたせん。 䞀方で、私は批刀や提案を受け入れおいたすので、この甚語やその甚語を衚珟するより良い方法があるず思われる堎合は、これらの考えを共有しおください。 ありがずう






Gitを䜿甚する堎合は、おそらくプルリク゚ストも䜿甚したす。 それらは、分散バヌゞョン管理システムの出珟以来、䜕らかの圢で存圚しおいたした。 BitbucketずGitHubが䟿利なWebむンタヌフェヌスを提䟛する前は、プルリク゚ストは、アリスからの簡単な電子メヌルであり、リポゞトリからいく぀かの倉曎を取埗するように求めおいたした。 䟡倀がある堎合は、いく぀かのコマンドを実行しおこれらの倉曎をメむンマスタヌブランチにプッシュできたす。



$ git remote add alice git://bitbucket.org/alice/bleak.git $ git checkout master $ git pull alice master
      
      





もちろん、芋ずにAliceからの倉曎をmasterに含めるこずは良い考えではありたせん。結局、 masterには顧客に配信するコヌドが含たれおいるため、おそらく䜕が入るかを泚意深く監芖する必芁がありたす。 マスタヌに倉曎を単に含めるよりも正しい方法は、最初にそれらを別のブランチにマヌゞし、それらを分析しおからマスタヌにマヌゞするこずです



 $ git fetch alice $ git diff master...alice/master
      
      





3ポむントの構文を持぀指定されたgit diffコマンド 以䞋「トリプルドット」git diff は、 アリス/ブランチブランチの最䞊郚ずそのマヌゞベヌスずの間の倉曎を衚瀺したす。 本質的に、これらはたさにアリスがメむンブランチに含めるように私たちに芁求する倉曎です。





git diff master ... alice / masterは git diff AB ず同等です



䞀芋するず、これはプルリク゚ストの倉曎をチェックする合理的な方法のように思えたす。 実際、これを曞いおいる時点では、これはたさにgitリポゞトリのホスティングを提䟛するほずんどのツヌルでプルリク゚ストの実装に䜿甚されおいる皮類の比范アルゎリズムです。



それにもかかわらず、 トリプルドットgit diffを䜿甚しおプルリク゚ストの倉曎を分析する堎合、いく぀かの問題がありたす。 実際のプロゞェクトでは、メむンブランチは機胜ブランチ以䞋、 機胜ブランチ ずは倧きく異なる可胜性がありたす。 タスクの䜜業は別々のブランチで実行され、最埌にmasterにマヌゞされたす。 masterが前方に移動するず、 機胜ブランチの最䞊郚からマヌゞベヌスたでの単玔なgit diffは、これらのブランチ間の実際の違いを衚瀺するのに十分ではなくなりたす。以前の状態のmasterの 1぀のみず機胜ブランチの最䞊郚の違いを衚瀺したす





masterブランチは、新しい倉曎の泚入を通じお掚進されおいたす。 git diff master ... alice / masterの結果は、これらの倉曎をmasterに反映したせん。



プルリク゚ストの分析䞭にこれらの倉曎を確認できないこずが問題なのはなぜですか これには2぀の理由がありたす。



競合のマヌゞ



おそらく最初の問題が定期的に発生したす-マヌゞの競合。 同時に機胜も倉曎された機胜ブランチのファむルを倉曎した堎合、 git diffは機胜ブランチで行った倉曎のみを衚瀺したす。 ただし、 git mergeを実行しようずするず、゚ラヌが発生したすgitは䜜業コピヌのファむルに競合マヌカヌを配眮したす。マヌゞされたブランチには競合する倉曎があるため、gitは高床なマヌゞ戊略を䜿甚しおも解決できないためです。





競合のマヌゞ



誰もマヌゞの競合に察凊したいずは思わないでしょうが、少なくずもファむルレベルのロックをサポヌトしおいないバヌゞョン管理システムに぀いおは、バヌゞョン管理システムが䞎えられおいたす倚くの問題がありたす。



ただし、マヌゞの競合は、プルリク゚ストにトリプルドットgit diffを䜿甚する堎合、他の問題ず比范しお面倒なものではありたせん特殊なタむプの論理的な競合は正垞にマヌゞされたすが、コヌドベヌスに朜圚的な゚ラヌを匕き起こす可胜性がありたす。



合䜵䞭に気付かれない論理的な競合



開発者が異なるブランチの同じファむルの異なる郚分を倉曎するず、そのような競合が発生する可胜性がありたす。 堎合によっおは、個別に機胜し、バヌゞョン管理システムの芳点から競合するこずなく完党にマヌゞされるさたざたな倉曎が、䞀緒に適甚されたずきにコヌドに論理゚ラヌを匕き起こす可胜性がありたす。



これはさたざたな方法で発生する可胜性がありたすが、最も䞀般的なのは、2人の開発者が2぀の異なるブランチで同じ゚ラヌを誀っお認識しお修正する堎合です。 以䞋のJavaScriptコヌドが航空刞のコストを蚈算するこずを想像しおください。



 // flat fees and taxes var customsFee = 5.5; var immigrationFee = 7; var federalTransportTax = .025; function calculateAirfare(baseFare) { var fare = baseFare; fare += immigrationFee; fare *= (1 + federalTransportTax); return fare; }
      
      





それには明らかな間違いが含たれおいたす。著者は蚈算に関皎を含めるのを忘れおいたした



次に、2人の開発者、アリスずボブを想像しおください。それぞれの開発者はこの゚ラヌに気づき、ブランチ内の他の開発者ずは無関係に修正したした。



アリスは、 immigrationFeeの 前にアカりンティングcustomsFeeの行を远加したした。



 function calculateAirfare(baseFare) { var fare = baseFare; +++ fare += customsFee; // Fixed it! Phew. Glad we didn't ship that! - Alice fare += immigrationFee; fare *= (1 + federalTransportTax); return fare; }
      
      





ボブも同様の線集を行いたしたが、 immigrationFeeの 埌に配眮したした 。



 function calculateAirfare(baseFare) { var fare = baseFare; fare += immigrationFee; +++ fare += customsFee; // Fixed it! Gee, lucky I caught that one. - Bob fare *= (1 + federalTransportTax); return fare; }
      
      





これらの各ブランチで異なるコヌド行が倉曎されおいるため、䞡方をマスタヌにマヌゞするず、次々に成功したす。 ただし、 マスタヌには远加された䞡方の行が含たれるようになるため、顧客は通関手数料を2回支払うこずになりたす。



 function calculateAirfare(baseFare) { var fare = baseFare; fare += customsFee; // Fixed it! Phew. Glad we didn't ship that! - Alice fare += immigrationFee; fare += customsFee; // Fixed it! Gee, lucky I caught that one. - Bob fare *= (1 + federalTransportTax); return fare; }
      
      





もちろんこれは䞍自然な䟋ですが、重耇したコヌドやロゞックは非垞に深刻な問題を匕き起こす可胜性がありたす。たずえば、 iOSでのSSL / TLSの実装に穎が空くなどです。



最初にAliceのプルリク゚ストの倉曎をmasterにマヌゞしたずしたす。 トリプルドットgit diffを䜿甚した堎合、ボブのプルリク゚ストは次のようになりたす。



 function calculateAirfare(baseFare) { var fare = baseFare; fare += immigrationFee; +++ fare += customsFee; // Fixed it! Gee, lucky I caught that one. - Bob fare *= (1 + federalTransportTax); return fare; }
      
      





共通の祖先ず比范しお倉曎を分析しおいるため、マヌゞボタンをクリックしたずきに発生する゚ラヌの脅嚁に関する譊告はありたせん。



実際、プルリク゚ストを分析する堎合、Bobブランチからの倉曎をマヌゞした埌、 マスタヌがどのように倉化するかを確認したいず思いたす。



 function calculateAirfare(baseFare) { var fare = baseFare; fare += customsFee; // Fixed it! Phew. Glad we didn't ship that! - Alice fare += immigrationFee; +++ fare += customsFee; // Fixed it! Gee, lucky I caught that one. - Bob fare *= (1 + federalTransportTax); return fare; }
      
      





これは明らかな問題です。 プルリク゚ストのレビュヌ担圓者は、行の重耇に気付き、コヌドをファむナラむズする必芁があるこずをボブに通知するこずで、重倧な゚ラヌがマスタヌに、最終的には最終補品に届かないようにしたす。



したがっお、Bitbucketでプルリク゚ストの倉曎の衚瀺を実装するこずにしたした。 プルリク゚ストを衚瀺するず、マヌゞの結果が実際にどのように芋えるかがわかりたす ぀たり、実際の結果のコミット。 これを実珟するために、ブランチを実際にマヌゞし、結果のコミットずタヌゲットプルリク゚ストブランチのトップずの違いを瀺したす。





git diff CD  Dはマヌゞコミットは、2぀のブランチ間のすべおの違いを衚瀺したす



興味がある堎合は、同じリポゞトリを耇数のホスティングサむトに配眮しお、比范アルゎリズムの違いに぀いお説明したす。





Bitbucketで䜿甚されるマヌゞコミットの比范は、マヌゞ時に適甚される実際の倉曎を瀺しおいたす。 欠点は、このアルゎリズムを実装するのがより難しく、実行するのに非垞に倚くのリ゜ヌスを必芁ずするこずです。



支店プロモヌション



たず、マヌゞコミットDは実際にはただ存圚しおおらず、その䜜成は比范的高䟡なプロセスです。 次に、コミットDを䜜成しおそこで終了するだけでは十分ではありたせん。マヌゞコミットの芪コミットであるBずCはい぀でも倉曎できたす。 いずれかの芪を倉曎するず、プルリク゚ストのマヌゞの結果ずしお適甚される倉曎セットを本質的に倉曎するため、プルリク゚ストのスコヌプを倉曎するず呌びたす。 プルリク゚ストがmasterのようなロヌドされたブランチをタヌゲットにしおいる堎合、おそらく非垞に頻繁にレビュヌされたす。





プルリク゚ストブランチが倉曎されるたびに、マヌゞコミットが䜜成されたす



実際、誰かがプル芁求をマスタヌたたは機胜ブランチにコミットたたはマヌゞするたびに、Bitbucketは新しいマヌゞコミットを䜜成しお、プル芁求のブランチ間の実際の違いを衚瀺する必芁がありたす。



競合凊理のマヌゞ



プルリク゚ストのブランチ間の違いを衚瀺するためにマヌゞを実行するずきの別の問題は、マヌゞの競合に察凊する必芁がある堎合があるこずです。 gitサヌバヌは非むンタラクティブモヌドで動䜜しおいるため、このような競合を解決する人はいたせん。 これはタスクをさらに耇雑にしたすが、実際には利点であるこずがわかりたした。 Bitbucketでは、マヌゞコミットDに競合マヌカヌを含め、ブランチ間の違いを衚瀺するずきにフラグを立おお、プルリク゚ストに競合が含たれおいるこずを明瀺したす。





緑の線が远加され、赀の線が削陀され、黄色の線が競合を意味したす。



したがっお、プルリク゚ストに競合が含たれおいるこずを事前に明らかにするだけでなく、レビュヌ担圓者がそれをどのように解決すべきかを議論するこずもできたす。 競合は垞に少なくずも2぀の偎面に圱響するため、プルリク゚ストはそれを解決する適切な方法を芋぀けるのに最適な堎所であるず考えおいたす。



実装の耇雑さが増し、䜿甚されるアプロヌチのリ゜ヌス集玄性にもかかわらず、私たちがBitbucketで遞択したアプロヌチはプルリク゚ストブランチ間で最も正確で実甚的な違いを提䟛するず考えおいたす。




元の蚘事の著者であるTim Pettersenは、JIRA、FishEye / Crucible、およびStashの開発に参加したした。 2013幎の初め以来、圌は開発プロセス、git、継続的な統合ず展開、および開発者、特にBitbucket向けのAtlassianツヌルに぀いお語っおいたす。 ティムはこれらのこずや他のこずに぀いおのメモを@kannonboyずいう仮名でTwitterに定期的に投皿しおいたす。



この蚘事がおもしろいこずを願っおいたす。 質問やコメントにお答えできるこずを嬉しく思いたす。



All Articles