web-dev-qa-db-ja.com

新しい開発者はブランチのマージについていけない

私は新しい開発者です。これが私の最初のプログラミングポジションです。

私の問題はこれです:gitを使用します-developブランチからブランチを切り取り、割り当てられたマイナータスクの作業を開始します。経験が浅いのでとても遅いです。私が自分のブランチをdevelopにマージする準備ができるまでに、他のメンバーは多くの変更を加えており、競合の解決は圧倒的です(実際に私の作業をスクラップしてタスクをやり直すのは簡単なようです)。もちろん、持続可能なソリューションではありません)。

どうすればこれを克服できますか? 「コーディングが得意」以外に使用できる戦術はありますか?私は来週上司にこれを持ち出すつもりです。

225
daisy

ブランチで行った変更が、その間に同僚がdevelopブランチで行った変更に近い場合、つまり、あなたと同僚が同じコード行または隣接する行を変更した場合、マージの競合が発生します。同じファイル。

したがって、マージの競合の可能性を減らすために、以前にマージして、同僚が変更する行を少なくするか、自分で変更する行を少なくすることができます。

自分で変更する行を少なくするには、タスクに関連する変更のみを行うようにしてください。

目標を達成するためにさまざまな方法で実験する必要がある場合、実際に変更する必要のない行を変更した実験があるかもしれません。マージする前にこれらの変更を元に戻します。

できるだけ少ない行を変更するのに役立ついくつかのGitコマンドもあります。

  • git diffおよびgit diff --stagedを使用して、変更した行を確認します。
  • git add -pを使用して、変更の一部のみをファイルに追加します。
  • git commit --amendおよびgit rebase -i to Tweakコミットは、他のGitリポジトリーにプッシュする前に、ローカル機能ブランチですでに作成したコミットです。

(変更する行をできるだけ少なくすると、作業の確認や、git cherry-pickgit rebasegit bisectgit blameなどのコミット間の違いを処理するツールの使用も簡単になります。)

ただし、マージの競合の可能性を減らしたとしても、マージの競合が発生することがあります。ですから、恐れることはありませんが、対立を解決する方法を学びましょう。

7
Toxaris

私はあなたがgitを使っていると思います。その場合は、git rebase -iを使用してください(-iはインタラクティブを意味します)。ブランチを開発ブランチに対してリベースすることを毎日のタスクにします(必要に応じて、さらに頻繁に)。これにより、変更が毎日(少なくとも)増分的に取り込まれ、機能ブランチが最新の状態に保たれます。毎日のリベース中に競合がある場合は、誰が何に取り組んでいるかについてチームと話し合う必要があります。

毎日実行する場合は、おそらくインタラクティブな部分は必要ありません。ただそれをやらせてください。

私はかなり経験豊富な開発者ですが、新しいプロジェクトに慣れるまでにはまだかなりの時間がかかります。あなたの場合、複数の人が同じプロジェクトに同時に取り組んでいるように聞こえるので、それは非常に大規模なプロジェクトか、急速に進化している新しいプロジェクトです。どちらの場合も、フローに入るのに数monthsかかることを心配しないでください。プロジェクトを2週間または3週間切り替えてから元に戻すと、自分で100%書き込んだプロジェクトに完全に「戻る」までに数時間(または1〜2日)かかる場合があります。

要するに、今のところ遅くなる心配はありません。良くなる方法は、ただ練習を続けることです。わからないプロジェクトの側面について他の開発者に尋ねることを恐れないでください。

編集:

または、mergeを使用します。それもオプションです。したがって、上記は「git rebase -i-iはインタラクティブを意味する」またはgit mergeを使用する」のようになります。どちらを使用するかについては、チームの他のメンバーと話し合ってください。彼らはどちらにしても強い好みを持っているかもしれないし、持っていないかもしれません。一部の人々doが強い好みを持っていることは明らかです。

286
Jacob Robbins

これは、会社側のソフトウェアエンジニアリングが悪いことを示している可能性があります。相互依存関係が多すぎる、機能が重複しているさまざまな問題、間違った順序で問題に取り組んでいるなど、説明している状況を引き起こす可能性があります。開発中は定期的にdevelopをブランチにマージすることをお勧めします

130

受け入れられた回答は、技術的な「Gitをよりよく使用する方法」という性質のものであり、エンジニアリングやツールの問題というより、チームの問題のほうが多いと思います。

マージの競合が多数発生している場合は、あなたとチームの他の誰かが互いにつま先を踏んでいることを意味します。
あなたまたは彼らはコーディング中に個人的な空間を開発することを目指し、すでに忙しい領域での作業を避ける必要があります。

私のチームでは、高度なタスク所有権を求める傾向があります。
私は通常、一度に2つまたは3つのファイルの完全かつ完全な所有権を取得し、ブランチで最大で1日または2日作業します。
通常、他の誰かがそれらのファイルに触れる場合は、自分のタスクに絶対に必要な場合にのみ、通常、同じタスクブロックで一緒に作業することはありません。

たくさんマージする必要がある場合は、すべてのチームコードを1か所に配置するか(それ自体は回避する必要があります)、すべてのタスクを配置します。

そうは言っても、あなたはおそらく新しい開発者として、何らかの種類の再構築を実施、要求、または提案する立場にないでしょう。
私が期待することは、あなたのタスクが、チームに参加しやすくするために、スキルレベルで合理的にアプローチできるはずの「ロープを学ぶ」ものとして割り当てられていることです。彼らはおそらく、同じ領域でまだ働いている同僚のタスクから間引かれているため、マージの競合が発生しています。
これに対する解決策は、それにプラグインし、問題を解決し、マージの競合にできる限り最善を尽くし、心配しないでください。最善を尽くしている限り、あなたのマネージャーはあなたの進歩について心配する必要があります。
行くにつれて、より速く、より自信が持てるようになり、同僚はより多くの自律性を与え、結果として邪魔にならないようになります。

97
Rowan

マージについて最も重要なことは、待つ時間が長くなるほど、痛みが大きくなることです。そして、問題は線形よりも大きくなります。紛争の3倍は仕事の9倍です。いくつかの戦略があります:

変更するたびに開発ブランチとマージするので、常にブランチに近づき、膨大な数の競合が発生することはありません。

時間がかかる場合は、ほとんどの時間を変更の内容の把握に費やしてから、変更の実装に少しの時間を費やしていることが原因である可能性があります。その場合は、実際のコード変更を開始する前に、開発ブランチとマージしてください。

競合を回避するための戦略について、同僚と話し合ってください。 2人が同じコードを編集すると、競合が発生します。同じファイルだけでなく、同じコード。したがって、新しい関数functionAが必要で、新しい関数functionBが必要です。両方とも同じファイルの最後に追加します。競合が発生します。別の場所に追加しても、競合はありません。論理的に属しているファイルの場所に両方を追加すると、競合が発生しない可能性があります。

If競合がある場合は、優れたdiffツールを入手して、マージ前の開発ブランチ、マージ前のコード、元のコード、およびマージされたコードを比較し、手動でマージできます。

最悪の場合:作業を破棄するのではなく、適切なdiffツールを使用して、行った変更を正確に見つけ、開発から再度分岐し、再入力する代わりに手動で加えたすべての変更を適用します。

29
gnasher729

準備ができるまでにmerge開発に戻る私のブランチ(強調は私のもの)

git mergeでの競合の処理は、多くの場合git rebaseよりも簡単です。 Gitマージでは、一度に変更されたファイルのリスト全体を確認できます。他の同僚が何回コミットしたかに関係なく、マージする必要がありますonce。リベースのワークフローでは、同じ競合が何度も繰り返され、手動で確認する必要がある場合があります。あなたは13番目のコミットを修正して、トンネルから光が見えないように感じることができます

私の経験では、繰り返しのリベースの競合を単純に解決しようとすると、誰かの変更が失われたり、コンパイルできなかったアプリケーションで失われたりしました。多くの場合、私と同僚は多くの作業を行いましたが、競合の繰り返しの複雑さに圧倒され、中止して、少数のリベースコミット後に以前の作業を失う必要がありました。

いくつかの手法を提案しますが、それらはマージをタスクの自動化よりも簡単にするのに役立ちます。

  • リソース/言語ファイル。リソースファイルにadditive変更がある場合は、それらを常にファイルの最後に移動して、簡単に呼び出すことができるようにしてくださいyourothers 'に対する変更。変更を下部にコピーして貼り付けるか、競合マーカーを削除することができます
  • しないでください。絶対に。再フォーマットしてください。あなたもあなたの仲間の開発者も、毎日の作業中に「大規模なコード再フォーマット」を実行してはなりません。コードの再フォーマットにより、競合管理に過剰な数の誤検知が追加されます。コードの再フォーマットが可能
    • 徐々に、例えばすべての開発者がすべてのコミットで、自動化ツールを使用するとすぐに(たとえば、Eclipseには保存時に再フォーマットするオプションがあり、Vanilla Visual Studioにはありません)。絶対にすべての開発者は、IDEが使用するフォーマットファイルにコード化された同じコードフォーマット標準を使用する必要があります。アイデアを与えるために、それが4つのスペースまたは2つのタブである場合、それは重要ではありませんが、誰もが同じものを使用するかどうかは本当に重要です。
    • リリース直前、チームリーダーによる。人々がブランチで作業していないときに、つまりブランチの前に「コード再フォーマット」コミットが発生した場合、物事はより簡単になります
  • レビュー同僚間の作業分割。これは、ほとんどのエンジニアリングがやって来る部分です。他の回答で指摘されているように、異なるタスクを実行している複数の開発者が同じリソースに触れなければならない場合、それはデザインのにおいです。各コンカレントデベロッパーが変更する部分について、チームリーダーと話し合う必要がある場合があります。

また、チームのGitワークフローでいくつかの悪い習慣を見てきました。多くの場合、人々は自分たちのブランチにコミットしすぎます。私は個人的に、開発者が「修正」というラベルの付いた10〜20のコミットを追加し、それぞれが1行または2行をコミットするのを目撃しました。私たちのポリシーは、コミットをJIRAチケットでラベル付けして、アイデアを提供することです。

@JacobRobbinsはgit rebaseを毎日の仕事にすることを提案しています。私は彼のアプローチを前進させたいと思います。

最初に、コミットの数を一握りに減らすためにリベースを一度だけ使用します。 original developブランチのみにリベースします。これは、ブランチのコミットです。一握りと言うときは、3または4(たとえば、すべてフロントエンド、すべてバックエンド、すべてのデータベースパッチ)または人間が合理的な図を意味する可能性があります。それらを統合した後、fetchを使用して、上流のブランチでリベースを実行します。これは、チームが独自のアプローチを検討しない限り、紛争からあなたを救うことはありませんが、あなたの人生の痛みを少なくします。

特定のタスクについて他に質問がある場合は、Stackoverflowで自由に検索して質問してください。

[編集]ノーフォーマットとボーイスカウトのルールについて。 RE-formatを少し書き換えて、私が意味しているのは、あなたが触れなかったコードを含むソースファイル全体を最初からフォーマットするタスクであることを強調します。常に独自のコードをフォーマットするのとは対照的に、これは完全にボーイスクーティーであり、IDEの機能を使用してファイル全体を再フォーマットするために、私を含む多くの開発者が使用されます。他の人がファイルに触れた場合、影響を受ける行の内容とセマンティクスが変更されていなくても、Gitはそれを競合と見なします。非常に強力な言語認識エディタのみが、競合がフォーマットにのみ関連していることを示唆し、最適なフォーマットのフラグメントを自動マージできます。しかし、そのようなツールの証拠はありません。

結局のところ、ボーイスカウトのルールでは、他の人の混乱をきれいにすることは義務付けられていません。あなただけのもの。

まず、変更を破棄することを考えないでください。マージプロセスを学ぶ機会を失います。

次に、競合を引き起こしているファイルに取り組んだ人を見つけます。歴史をご覧いただけます。その人と話し、それらのファイルの競合を解決します。他の競合についても同じようにします。

競合が多すぎる場合、タスクはマイナーなものになる可能性がありますが、反復的です。パターンを見つけてみてください。これは、Git UIクライアントツールによる競合の解決に役立ちます。 TortoiseGitを使用しています。マージに役立ちます。

そして将来の回避のために

  • 定期的に開発ブランチを機能ブランチにマージすることは非常に良い習慣です。

  • CIを有効にしている場合は、CIツールがブランチビルドを提供しているかどうかを確認します。これは、機能ブランチで行うすべてのチェックインに基づいて構築されますが、マージ開発ブランチの後です。

6
PKV

ここにはいくつかの根本的な問題があります。マージする問題はおそらくあなたのせいではなく、より一般的には悪い習慣の症状です。

1)理想的には、ブランチをマージして毎日開発します。少なくとも1日に1回はすべてのテストに合格する動作中のコードを作成して、開発にマージできるようにしてください。

2)通常の作業日のどの時点でも機能するコードがない場合は、コードのチャンクが大きすぎて作業できない可能性があります。マージできるように、タスクを(理想的には互いに独立して)より速く終了できる小さなタスクに分割する必要があります。

3)プロジェクトファイルが大きすぎる可能性があります。ファイルのマージ競合が多い場合、1つのファイルで作業している人が多すぎます。理想的には、1人が取り組んでいるものは、他の全員が取り組んでいるものとは別のものである必要があります。

4)チームが大きすぎる可能性があります。機能全体を破棄して最初からやり直す方が簡単である場合は、同じリポジトリにコードをコミットする人が多すぎる可能性があります。

5)一貫したコードフォーマット標準がない場合があります。同じコードのフォーマット設定を一貫して使用しないと、同じコードに対してさまざまな競合が発生します。 gitの設定方法によっては、空白の競合(行末、インデント、タブvsスペース)が発生することもあります。

6)人々は変更を直接開発ブランチにプッシュしている可能性があります。

あなたができることは次のとおりです。1)毎日開発にマージできない場合は、毎日(またはより頻繁に)開発にブランチにマージ/リベースします。
2)コードを他のすべてのコードから分離するようにしてください。
3)小さい機能、一貫したコーディング標準、およびより良いコード編成(小さいファイル、小さい関数)について、チームの他のメンバーと話します。

2
xyious

実際に私の仕事をスクラップしてタスクをやり直す方が簡単に思えますが、これはもちろん持続可能なソリューションではありません)

ほとんどの場合、これは私が行うことであり、初めてバグを修正したり、システムに変更を加えたりするときに、その方法を学んでいます。次に同じバグを修正するとき、問題を理解したので、時間の1%しかかかりません。

また、少し作業をやり直すと、より良いコードを書くようになります。

したがって、マスターから新しいブランチを作成して作業をやり直し、「プライベートブランチ」を使用して何をする必要があるかを思い出させても問題はありません。

変更を論理的で正しい部分に分割する方法を発見した可能性もあります。各部分は、完了したらマスターブランチにマージされます。たとえば、ユニットテストとバックエンドコードの変更を行ってマージできます。次に、別の操作で、それらを利用するUIの変更を行うことができるため、他の誰かが同じUIファイルを編集するリスクが少なくなります。

1
Ian

開発ブランチを頻繁にマージしたくない場合は、git pull --rebaseを使用して、svnに近いワークフローを取得できます。これにより、新しいコミットがプルされ、コミットがリベースされます。つまり、ブランチを開発にマージすると、それは早送りマージとなり(過去のコミットをすべて同時に次々に追加した場合と同じように)、マージ中に競合が解決されるため、マージの競合は発生しません。 git pull --rebase

しかし、ブランチを開発にマージするか、ブランチにマージする前にコミットを増やすと、次のリベースがより複雑になり、機能ブランチの感覚が少し損なわれます。ブランチがマージされていない間だけ存在するからです。 。

1
allo

明らかに最初のことは、少なくとも困難な競合を引き起こすような方法で、最初から複数の人が同じファイルで作業することを避けることです。列挙型に何かを追加しても、適切なコード形式が使用されている限り問題ありません。制御フローをさまざまな方法で変更し、コードを移動することは、はるかにトリッキーです。それでも、これは避けられないことがあります。本当に複雑な衝突を解決するときは、質問をする必要があります。

そうは言っても、定期的に開発にマージ/リベースすることを推奨する多くの回答が見られます。私はそのようなアドバイスについてはそれほど熱狂的ではないでしょう。この時点での目標は、紛争解決プロセスを可能な限り簡単かつ安全にすることです。そのプロセスで非常に役立つ1つのことは、新しい機能の一部である新しいものを含め、できるだけ多くの回帰テストをすぐに利用できるようにすることです。ブランチを定期的に開発と同期させると、実際に機能の実装が半分完了するまで、常に競合を解決する必要があります。そして、それはあなたがそれで終わっていなかったので、コードが何をすることになっているのか理解しようとすることははるかに難しくなることを意味します。マージを試みる前に、ブランチが一貫した変更の単位であることを確認してください。さらに良いことに、マージする前に単一のコミットにリベースします。

おそらく別の質問のために、マージよりもリベースのメリットに触れないようにしました。このコンテキストでは、ツールはそれほど重要ではありません。

1
Kafein

私は自分のブランチをマージして開発に戻す準備ができたときまでに、競合を解決することは圧倒的なほど多くの他の変更を加えました

これは ペアプログラミング の理想的なシナリオのように思えます。

利点と基本的なアプローチの詳細:
https://gds.blog.gov.uk/2018/02/06/how-to-pair-program-effectively-in-6-steps/

自分で作業することにより、時間の経過とともに自然にスピードアップしますが、その時が来るまで気が遠くなることもあります。また、人々は常に追いつくようにプレッシャーをかけられているストレスの多い環境にいることをすぐに学ぶことができますが、一定のプレッシャーの下でうまく学習しない人は妨げられます。

自分でブランチに取り組んで、明らかに自分よりはるかに速い他の開発者に追いつくのではなく、別の開発者と直接(同じPCで)作業します。このようにすれば、すぐにアドバイスが得られ、速度を上げる方法などのヒントが得られます。

ペアプログラミングは必ずしも一部のプロジェクトでは意味をなさないため、プロジェクトの特定のコードに最適なアプローチを理解する必要があります。 (彼らが優れた開発者である限り、経験は必ずしも彼らが優れた実践を使用することを意味するわけではありません)。

より速く、より経験豊富な開発者と一緒に座っていると、次のことで役立つ可能性があります。

  • 経験豊富な誰かと一緒に作業すると、単独で作業するのではなく、完了時間が長くなるため、マージの競合が減少する可能性があります。
  • 彼らはあなたに教えるので、彼らが一人で作業するよりも遅くなる可能性が高いので、まだマージの競合があり、熟練した誰かとそれらを介して作業できるので、時間を節約するためのいくつかのヒントを拾うなど
  • 潜在的なトリックとより速くなる方法を確認するのに役立ちます(ただし、遅いのは、単に良い習慣がないというより、単に経験がないという場合もあります)。
  • 何かが意味をなさない、または100%明確ではない場合、すぐに質問できます
  • 1:1で作業することは学習に役立ちます。助けを求める人は、作業中の正確なコードとシナリオをすでに理解しているため、ペアプログラミングをしないと、コードとシナリオを説明する必要があり、問題が発生しやすくなります。そのため、実際に多くの必要なアドバイスを得ることに時間と注意を失う
  • より経験と経験のある人の思考プロセスを理解し、適切なコミュニケーションにより、新しいことを確実に学ぶことができます

「コーディングが得意」以外に使用できる戦術はありますか?私は来週上司にこれを持ち出すつもりです。

私のアドバイスは、ペアプログラミングについて他の開発者と話し合ってから、上司に連絡することです。彼らがきちんとしている場合、彼らはあなたがペアプログラミングのプロを売り込むより多くの機会を持っているあなたのイニシアチブを高く評価するでしょう(彼らがそれを必要とするなら、ほとんどの人はそれを知っており、それがなぜ役立つのかという共通の知識です)。

1
James

共通ファイルで作業する場合、マージが完了する前に、あなたまたはチームメイトがすべての競合を解決する必要があるため、そもそも動揺しないでください。あなたはまだプロジェクトの仕事をしていて、自分の仕事に誇りを持っています。よりスマートな動きをするために、以下のいくつかの提案に従うことができます。

  1. タスクを個別に分割します。

    作業を開始する前に、各チームメンバーに割り当てられたタスクが可能な限り独立してモジュール化されるように(開発中の潜在的な競合を回避するため)、タスク全体を計画および分割します。あなたは初心者なので、スクラムリーダーに近づいていくつかの独立したタスクを割り当てることができます。
  2. 細かい頻繁なコミットをマージします。

    最終的なマージの前に、完全なタスクが完了するのを待たないでください。もちろん、より大きなタスクは複数のサブタスクに分割できます。したがって、より良いアプローチは、大きなサブタスクの小さなコミットを同時に頻繁にマージして、大きな競合の解決を回避することです。
  3. ブランチを頻繁にリベースする:

    リモートブランチを使用してローカルブランチに頻繁にリベースする練習をしてください。以下のコマンドを使用して、ローカルブランチをリモートブランチに頻繁にリベースできます。

    git pull --rebase #or
    git pull --rebase Origin dev #when dev is remote branch
    

    これは、これまでのところ、私の開発生活の中で最も便利なgitコマンドです。

  4. チームメイトと緊密に連携する:

    共通のタスクでチームメイトと並行して作業する必要がある場合は、共同で作業してください。あなたは初心者であり、彼女は専門家であるため、彼女はあなたの便宜のために複雑な紛争解決を避けるためにしばらく待つことができます。

  5. Gitオプションを使用する:

    Gitマージツールの機能を使用します。マージ中に競合を解決するには、多くの便利な方法があります。 統合戦略 は、多くの場合役立つことがあります。 gitコマンドでfearlessに慣れている。

1

開発ブランチから定期的に(毎日)コマンドgit fetch(git pullではない)を実行する必要があります。これにより、他の人々がコミットした変更を取得し、変更をブランチに統合しようとせずにそれらを機能ブランチに取り込みます。

これは、あなたの会社がこの問題を処理するための独自の基準または推奨される方法を持っている可能性があるため、リード開発者(必ずしもマネージャーではない)と話す必要があるものです。それは非常に一般的です。来週まで待ってはいけません-今すぐプロセスを見つけて、プロセスをテストできるように、簡単な作業(コードのフォーマットやコメントの追加など)をコミットできるかどうか尋ねてください。

1
PeteCon