ホームページ  >  記事  >  開発ツール  >  git でのマージとは

git でのマージとは

青灯夜游
青灯夜游オリジナル
2021-12-29 17:41:3619126ブラウズ

git では、merge は「マージ」を意味します。このコマンドは、2 つ以上の開発履歴をマージするために使用されます。merge コマンドは、git-pull で別のリポジトリの変更を統合するために使用できます。あるブランチから別のブランチにマージします。

git でのマージとは

このチュートリアルの動作環境: Windows 7 システム、Git バージョン 2.30.0、Dell G3 コンピューター。

git-merge 完全解析

Git の git-merge は Git でよく使われるコマンドですが、git merge というと非常に面倒なことだと思っている人が多いです。コードが失われるという問題が発生し、git を敬遠することになります。この記事では、Git 2.8.2 に基づく git-merge コマンドの完全かつ詳細な紹介を提供します。特に、クロスマージによって引き起こされるコード損失の問題に関して、記事の最後に私自身の提案を示します。git ユーザーの助けになることを願っています。 。この記事で紹介する内容は Git 2.8.2

git-merge コマンドは、2 つ以上の開発履歴をマージするために使用されます。通常、git merge とも記述できます。

1.git-merge 関連のオプション パラメータ

1.1 概要

git-merge コマンドには、次の 3 つのパラメータがあります。

  • git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] [-s <strategy>] [-X ] [-S[<keyid>]] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]</commit></msg></keyid></strategy>
  • #git merge HEAD ...
  • git merge --abort
#1.2git の概要-merge

git-merge コマンドは、指定されたコミットから現在のブランチにマージするために使用されます。

注: ここで指定されたコミットは、これらの履歴コミット ノードから開始して現在の分離までを指します。

git-merge コマンドには次の 2 つの用途があります。

    は、別のコード リポジトリの変更を統合するために git-pull で使用されます (例: git pull = git fetch) git merge)
  1. あるブランチから別のブランチにマージする場合
次の履歴ノードが存在し、現在のブランチが「マスター」であると仮定します。


git でのマージとは

次に、

git merge topic コマンドは、マスター ブランチ上の共通ノード (E ノード) の後に分離されたノード (トピック) をマージします。 ) は、トピック ブランチ (C ノード) の現在のコミット ノードまでマスター ブランチに再表示され、マスター ブランチの最上位に配置されます。そして、マスター ブランチとトピック ブランチに沿って新しいノードを作成し、マージ結果を記録します。このノードには、マージの変更を説明するユーザーの情報が含まれます。

つまり、下図の H ノード、C ノード、G ノードはいずれも H ノードの親ノードです。

git でのマージとは##1.3

git merge HEAD ...

Commandこのコマンドの存在期限歴史的な理由により、新しいバージョンでは使用しないでください。

git merge -m ....

を代わりに使用してください1.4

git merge --abort

コマンドこのコマンドは、マージ後に競合が発生した場合にのみ使用されます。

git merge --abort

はマージ プロセスを放棄し、マージ前の状態を再構築しようとします。ただし、マージ開始時にコミットされていないファイルがある場合、git merge --abort はマージ前の状態を再現できない場合があります。 (特に、これらのコミットされていないファイルがマージ プロセス中に変更される場合)

警告:
git-merge

を実行すると、コミットされていないファイルが大量に含まれやすくなります。紛争で後退するのが困難な状況にある。したがって、git-merge を使用する場合は、コミットされていないファイルを使用することは強くお勧めできません。git-stash コマンドを使用して、これらのコミットされていないファイルを一時的に保存し、競合を解決した後に使用することをお勧めします。 git stash Popこれらのコミットされていないファイルを復元します。

2. パラメータ

このセクションでは、

git-merge

コマンド2.1

- で使用されるパラメータを紹介します。 -commit

および --no-commit

--commit

パラメーターを使用すると、マージ後にマージ結果のコミット ノードが生成されます。このパラメータは --no-commit をオーバーライドできます。 --no-commit
パラメーターを使用すると、マージの失敗を防ぐためにマージが自動的に送信されなくなり、送信前にマージ結果を確認して変更する機会がユーザーに与えられます。 2.2

--edit

および -e および --no-edit

--edit

-e は、マージと送信が成功する前に、エディターを呼び出して、自動的に生成されたマージ情報をさらに編集するために使用されます。したがって、ユーザーは合併の結果をさらに解釈し、判断することができます。 --no-edit
パラメータを使用すると、自動的にマージされた情報を受け入れることができます (これは通常は推奨されません)。 <blockquote><p>マージ時に <code>-m パラメータを指定した場合 (後述)、--edit (または -e) を使用すると便利です。 、これにより、エディタで -m に含まれるコンテンツがさらに編集されます。

ノードの古いバージョンでは、ユーザーがマージ ログ情報を編集できない場合があります。

2.3--ffコマンド

--ff は、早送りコマンドを指します。早送りモードを使用してマージする場合、新しいコミット ノードは作成されません。デフォルトでは、git-merge は早送りモードを採用します。
早送りモードの詳細な説明については、私の別の記事「成功した Git ブランチ モデルの「早送りについて」セクション」を参照してください。

2.4--no-ffコマンド

早送りモードが使用できる場合でも、新しいマージ ノードを作成します。これは、git merge がタグをマージするときのデフォルトの動作です。

2.5--ff-onlyCommand

現在の HEAD ノードが最新 (更新が最新のノードを指す) または早送りモードでない場合マージを使用できます。そうでない場合、マージは拒否され、失敗ステータスが返されます。

2.5 --log[=<n>]</n> および --no-log

--log[=&lt ;n>] マージして送信すると、ブランチ名に加えて、最大 n 個のマージされたコミット ノードのログ情報も含まれます。
--no-log では、この情報はリストされません。

2.6 --stat-n--no-statコマンド

--stat このパラメーターは、マージ結果の最後にファイルの差分のステータスを表示します。ファイル差異のステータスは、git 設定ファイルの merge.stat で設定することもできます。
対照的に、-n--no-stat パラメーターでは、この情報は表示されません。

2.7--squash および --no-squash

--squash マージが発生すると、現在のブランチと他のブランチの共通祖先ノードの後に​​他のブランチ ノードを追加し、他のブランチの最上位ノードまで圧縮します。ユーザーはレビュー後に送信して新しいノードを生成できます。

注 1: このパラメータは --no-ff と競合します

##注 2: このパラメータを使用した後の結果は次のようになります。現在のブランチに新しいノードをコミットします。このパラメーターは、Git Flow を使用する場合など、場合によっては非常に役立ちます (Git Flow については、「成功した Git ブランチ モデル」を参照してください)。関数ブランチが機能要件を開発しているとき、開発者はローカルで多数の要件を送信することがあります。また、意味のないノードは、develop ブランチにマージする必要がある場合、この長いノード リストの変更内容を表すために新しいノードを使用するだけで済みます。 #コマンドが活躍します。さらに、機能ブランチの複数の送信が簡単ではないが意味がある場合は、

--no-ff コマンドを使用する方が適切です。 --no-squash はまったく逆の効果があります。
2.8

-s
および

--strategy=##-s <strategy> および </strategy>

--strategy=

は、マージ戦略を指定するために使用されます。デフォルトでは、このパラメータが指定されていない場合、git は次の条件に従ってデフォルトのマージ戦略を使用します。 マージ ノードに 1 つの親ノードのみが含まれる場合 (早送りを使用する場合など)モード)、再帰的戦略が使用されます (以下で紹介します)。

マージされたノードに複数の親ノードが含まれる場合 (早送りなしモードを使用している場合など)、タコ戦略 (後述) が使用されます。
  1. 2.9
  2. -X
  3. and
--strategy-option=

- ■ <strategy></strategy>、戦略の特定のパラメータを指定します (後述)。

2.10 --verify-signatures

--no-verify-signatures

は、マージされたノードに GPG 署名があるかどうかを検証するために使用されます。 、マージでは GPG 署名検証のないノードを無視します。 (以下は転載記事からの引用です。原著者が見つからないため、原著者情報と原リンクを提供できません。侵害がある場合は、プライベートメッセージまたはコメントでお知らせください。 、次の引用は削除させていただきます。)

GPG は暗号化ソフトウェアです。GPG によって生成された公開キーを使用して、ファイルやコードをインターネット上に安全に拡散できます。
なぜ安全だと言えるのですか? Google が開発したリポジトリを例に挙げると、リポジトリでは GPG 検証が使用されています。各マイルストーン タグには GPG 暗号化検証が含まれています。マイルストーン v1.12.3 で変更を加えたい場合は、変更後にタグを削除すれば確実に可能です。同じ名前のタグを作成して、変更点を指します。ただし、変更したプロジェクトを再度複製すると、このマイルストーン タグへの変更が認識されず、検証が失敗し、変更がここで正常に実装されないことがわかります。これは GPG 検証の役割であり、プロジェクト作成者 (秘密鍵所有者) によって設定されたマイルストーンが他の人によって変更できないことを保証します。そうすれば、作成者のコードは安全に配布されたと言えます。
なぜそのような必要があるのでしょうか?プロジェクトの開発からリリース、その後の更新反復まで、多数の安定バージョンと開発バージョンが確実に存在します (不安定要素があります)。プロジェクトの開始者および所有者は、自分たちが認識する安定バージョンを定義する権利を持ち、この安定バージョンには他の開発者による変更は許可されません。 Google のリポジトリ プロジェクトを例に挙げると、プロジェクト オーナーはプロジェクト開発プロセスのポイント A を安定バージョン v1.12.3 として定義します。ユーザーは v1.12.3 バージョンをダウンロードすると、ポイント A によって生成されたプロジェクトと製品を確実に使用します。たとえ他の開発者が v1.12.3 をローカルで再指定し、修正点 B に指定できたとしても、修正版が最終的にユーザーによって使用されるときに、GPG 署名の検証が失敗するという問題が発生します。変更は有効になりません。

2.11 —概要,--概要なし

および--統計および --no-stat も同様ですが、将来のバージョンでは削除される予定です。

2.12 -q および --quize

はサイレントに動作し、マージの進行状況情報は表示されません。

2.13 -v および --verbose

は、マージ結果の詳細情報を表示します。

2.14 --progress および --no-progress

は、マージされた進行状況情報を表示するかどうかを切り替えます。どちらも指定しない場合は、標準エラー発生時に接続端末にメッセージが表示されます。すべてのマージ戦略が進行状況レポートをサポートしているわけではないことに注意してください。

2.15-S[<keyid>]</keyid> および --gpg-sign[=<keyid>]</keyid>

GPG 署名。

2.16-m <msg></msg>

マージノード作成時に使用するコミット情報を設定します。
--log パラメーターが指定されている場合、コミット ノードの短いログがコミット情報に追加されます。

2.17--[no-]rerere-autoupdate

rerere は、記録された解像度を再利用する、記録されたソリューションを再利用することを意味します。これにより、ブロックの競合を解決する方法を Git に記憶させ、次回同じ競合が発生したときに Git が自動的に解決できるようにすることができます。

2.18--abort

現在のマージ競合処理プロセスを放棄し、マージ前の状態の再構築を試みます。

3. マージに関するその他の概念

3.1 マージ前の検出

外部ブランチをマージするときは、自分のブランチをクリーンな状態に保つ必要があります。そうしないと、マージ競合が発生します。多くの問題を引き起こします。
コミットをマージするときに無関係なファイルが記録されるのを避けるため、インデックスが指す HEAD ノードにコミットされていないファイルが登録されている場合、git-pull および git-merge コマンドは停止します。

3.2早送りマージ

通常、ブランチ マージではマージ ノードが生成されますが、いくつかの特殊なケースでは例外があります。たとえば、git pull コマンドを呼び出してリモート コードを更新する場合、ローカル ブランチにコミットがない場合は、マージ ノードを生成する必要はありません。この場合、マージ ノードは生成されず、HEAD は更新されたトップ コードを直接ポイントします。このマージ戦略は早送りマージです。

3.3 マージの詳細

上記の早送りマージ モードに加えて、マージされたブランチはマージ ノードを介して現在のブランチに結び付けられます。マージ前の現在のブランチのノードと他のブランチの最上位ノード (両方とも親ノード)。
マージされたバージョンでは、コミット ノード、HEAD ノード、インデックス ポインターを含む、関連するすべてのブランチの変更の一貫性が保たれ、ノード ツリーが更新されます。これらのノード内のファイルが重複しない限り、これらのファイルへの変更はノード ツリー内で変更および更新されます。
これらの変更を明らかにマージできない場合、次のことが起こります:

  1. HEAD ポインタが指すノードは変更されません。
  2. MERGE_HEADポインタは他のブランチの上に配置されます。
  3. クリーン パスがマージされました。インデックス ファイル ノード ツリーと同時に更新されます。
  4. 競合パスの場合、インデックス ファイルには 3 つのバージョンが記録されます。バージョン 1 は両方の共通の祖先ノードを記録し、バージョン 2 は現在のブランチの先頭、つまり HEAD を記録します。 、バージョン 3 レコードは MERGE_HEAD です。ノード ツリー内のファイルには、マージ プログラムの結果が含まれています。たとえば、3 方向マージ アルゴリズムでは競合が発生する可能性があります。
  5. その他の変更はありません。特に、以前に行ったローカルな変更はそのまま残ります。
    マージを試みた結果、非常に複雑な競合が発生し、最初からやり直したい場合は、git merge --abort

約 3- を使用できます。ウェイ マージ アルゴリズム:
3 ウェイ マージ アルゴリズムは競合を解決する方法です。競合が発生すると、3 ウェイ マージ アルゴリズムは 3 つのノードを取得します: ローカル競合の B ノード、もう一方の C ノードブランチ、B ノードと C ノード、共通の最新の祖先ノード A。 3 方向マージ アルゴリズムは、これら 3 つのノードに基づいてマージします。具体的なプロセスは、ノード B および C をノード A と比較することです。ノード B および C のファイルがノード A のファイルと同じである場合、ノード B または C のいずれか 1 つだけがノードと比較して変更されている場合、競合は発生しません。 A の場合、ファイルは変更されたバージョンを採用します。A と比較して B と C が変更され、その変更が同じでない場合は、それらを手動でマージする必要があります。B と C が変更され、変更が同じである場合そうすると競合は発生せず、変更されたバージョンが自動的に採用されます。最終的なマージの後、D ノードが生成されます。D ノードには、B と C という 2 つの親ノードがあります。

3.4 タグのマージ

タグをマージすると、現時点で早送りモードが使用できる場合でも、Git は常にマージされたコミットを作成します。タグの情報には、投稿情報のテンプレートがあらかじめ設定されています。さらに、タグが署名されている場合、署名検出情報がコミット メッセージ テンプレートに追加されます。

3.5 競合の表現方法

マージ競合が発生すると、この部分は , # で終了します。 ##========<code> と >>>>>>> を表します。 ======= より前が自ブランチの状況、 ======== より後が相手ブランチの状況です。 。

3.6 競合を解決する方法

競合を確認した後、次の 2 つの方法を選択できます。

    マージしないことを決定します。現時点では、インデックスを HEAD ノードにリセットするだけです。この場合は
  • git merge --abort が使用されます。
  • 競合を解決します。 Git は競合をマークします。競合を解決したら、
  • git add を使用してインデックスに追加し、git commit を使用してマージ ノードを生成します。 次のツールを使用して競合を解決できます:
  • マージ ツールを使用します。
  • git mergetool は、競合するマージを処理するためにビジュアル マージ ツールを呼び出します。
  • 違いを確認してください。
  • git diff は、3 方向の差分 (3 方向マージで使用される 3 方向比較アルゴリズム) を表示します。
  • 各ブランチの違いを確認してください。
  • git log --merge -p は、HEAD バージョンと MERGE_HEAD バージョンの違いを表示します。
  • マージ前のバージョンを表示します。
  • git show :1:ファイル名共通祖先のバージョンを表示します。git show :2:ファイル名現在のブランチの HEAD バージョンを表示します。git show :3 :ファイル名相手のブランチのMERGE_HEADバージョンを表示します。
4. マージ戦略

Git では、-s パラメーターを追加することでマージ戦略を指定できます。一部のマージ戦略には独自のパラメータ オプションもあります。これらのマージ戦略のパラメータ オプションを設定するには、

-X

4.1resolve

3 方向マージ アルゴリズムは、2 つのブランチ (現在のブランチとプルダウンした別のブランチなど) の最上位ノードをマージする場合にのみ使用してください。このマージ戦略は 3 方向マージ アルゴリズムに従い、2 つのブランチの HEAD ノードと共通の子ノードが 3 方向マージを実行します。

もちろん、本当に気になるのはクロスマージ(十字併合)の状況です。いわゆるクロスマージとは、複数の共通の祖先ノードが存在する状況を指します。たとえば、2 つのブランチをマージする場合、2 つの共通の祖先ノードが存在する可能性が非常に高くなります。現時点では、それに応じてマージを実行できません。 3 方向マージ アルゴリズムに変換します (共通祖先ノードが一意ではないため)。これは、解決戦略がクロスマージ問題を処理する方法です。ここでは、「Git によるバージョン管理」を参照してください:

複数の可能なマージ ベースがある、交差マージの状況では、解決戦略は次のように機能します: 可能なマージ ベースの 1 つを選択し、最善の結果を期待します。これは実際にはそれほど悪くありません。そうですね。ユーザーがコードの別の部分で作業していることが判明することはよくあります。その場合、Git は、すでに存在している変更の一部を再マージしていることを検出し、重複する変更をスキップして競合を回避します。これらは競合を引き起こすわずかな変更であり、少なくとも開発者が競合を簡単に処理できるようにする必要があります。祖先ノード)、解決戦略は次のように機能します。考えられるマージ参照ポイントの 1 つを選択し、これが最良の結果であることを望みます。合併中。これは実際のところ、思っているほど悪くはありません。通常、ユーザーはコードのさまざまな部分を変更しますが、その場合、多くのマージ競合は実際には冗長で反復的になります。解決を使用してマージすると、生成された競合の処理が容易になり、実際にコードが失われるケースはほとんどありません。

4.2recursive

2 つのブランチをマージする場合は、3 方向マージ アルゴリズムのみを使用してください。解決とは異なり、クロス マージの場合、このマージ メソッドは再帰的に呼び出されます。共通の祖先ノードの後の 2 つのブランチの異なるノードから開始して、3 方向マージ アルゴリズムが再帰的に呼び出されてマージされます。競合が発生した場合は、その後、ファイルのマージは続行されなくなり、競合が直接スローされます。競合のない他のファイルは最上位ノードまで実行されます。さらに、このアプローチでは、ファイル名の変更を伴う操作を検出して処理できます。これは、git のマージおよびコードのプルのデフォルトのマージ アクションです。

再帰的マージ戦略には次のパラメータがあります:

4.2.1 ours

このパラメータは、競合が発生したときに現在のブランチのバージョンが自動的に使用されるように強制します。このマージ方法では問題は発生せず、git でも他のブランチのバージョンに含まれる競合内容をチェックせず、他のブランチの競合内容を破棄します。

4.2.2 彼らの

は私たちのものとはまったく逆です。

彼らのパラメータと私たちのパラメータはどちらも、バイナリ ファイルの競合をマージするのに適しています。

4.2.2 忍耐力

このパラメータを使用すると、

git merge-recursive

重要でない行 (関数など) の括弧の欠落を避けるために、余分な時間を費やします)。現在のブランチと他のブランチの間のバージョン ブランチの分離が非常に大きい場合は、このマージ方法を使用することをお勧めします。

4.2.3diff-algorithm=[patience|minimal|histogram|myers]

情報git merge-recursive

別の比較アルゴリズムを使用する。

4.2.4 ignore-space-change

ignore-all-spaceignore-space-at-eol 指定されたパラメータに従ってスペースの競合を処理します。

相手のバージョンがスペースの変更のみを追加する場合、競合がマージされるときに自分のバージョンが使用されます

    自分のバージョンにスペースが含まれているが、相手のバージョンに多数の変更がある場合、競合がマージされるときに相手のバージョンが使用されます
  • 通常の処理プロセスを使用します
  • 4.2.5
  • no-renames

名前変更の検出を閉じます。

4.2.6

subtree[=]

このオプションは、サブツリー マージ戦略の高度な形式であり、2 つのノード ツリーをマージするプロセスを推測します。 . 入居方法。違いは、指定されたパスがマージの開始時に削除されるため、サブツリーを検索するときに他のパスが照合できることです。 (サブツリー マージ戦略の詳細については、以下を参照してください)

4.3octopus

このマージ方法は 3 つ以上のブランチに使用されますが、競合により手動マージが必要な場合はマージが拒否されます。このマージ方法は、複数のブランチをバンドルするのにより適しており、複数ブランチのマージのデフォルトのマージ戦略でもあります。

4.4ours

このメソッドは任意の数のブランチをマージできますが、ノード ツリーのマージ結果は常に現在のブランチの競合部分になります。この方法は、古いバージョンを置き換える場合に非常に効率的です。このメソッドは、再帰的戦略におけるパラメータとは異なることに注意してください。

4.5subtree

サブツリーは、再帰戦略の修正バージョンです。ツリー A とツリー B をマージする場合、B が A のサブツリーである場合、B は同じノードを読み取るのではなく、まず A のツリー構造に一致するように調整します。

4.5 概要

3 方向マージ戦略 (デフォルトの再帰戦略を参照) を使用する場合、現在のブランチと他のブランチの両方でファイル (またはコード行) が変更された場合、その後、ブランチの 1 つにロールバックします。

その後、このロールバックの変更が結果に反映されます

。この点で混乱する人もいるかもしれません。これは、マージ プロセス中、git は 2 つのブランチのすべてのノードではなく、2 つのブランチの共通の祖先ノードと HEAD ノードのみに焦点を当てるためです。したがって、マージ アルゴリズムはロールバックされた部分を

unchanged とみなし、マージされた結果が他のブランチの変更された部分になります。 推奨学習:「Git チュートリアル

以上がgit でのマージとはの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。