この記事では、Git に関する関連知識を提供します。主に git-merge の関連問題について紹介します。git-merge コマンドは、指定されたコミットから現在のコミットの操作にマージするために使用されます。ブランチ、皆さんのお役に立てれば幸いです。
推奨学習: 「Git チュートリアル 」
git-merge 内command には次の 3 つのパラメータがあります:
git merge [-n] [--stat] [--no-commit] [--squash] [--[no- ]編集] [-s ] [-X ] [-S[<keyid>]] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]</msg></keyid>
git-merge コマンドには次の 2 つの用途があります。は、別のコード リポジトリの変更を統合するために git-pull で使用されます (例: git pull = git fetch) git merge)
コマンドがマスター ブランチで実行されます。分離されたノード(つまり、トピック ブランチの A B C ノード) は、共通ノード (E ノード) からトピック ブランチの現在のコミット ノード (C ノード) までマスター ブランチ上に再表示され、マスター ブランチの先頭に位置します。そして、マスター ブランチとトピック ブランチに沿って新しいノードを作成し、マージ結果を記録します。このノードには、マージの変更を説明するユーザーの情報が含まれます。 1.3
このコマンドは歴史的な理由から存在しており、新しいバージョンでは使用しないでください。 1.4
に置き換えます。このコマンドは、マージ後に競合が発生した場合にのみ使用されます。 はマージ プロセスを放棄し、マージ前の状態を再構築しようとします。ただし、マージ開始時にコミットされていないファイルがある場合、git merge --abort
はマージ前の状態を再現できない場合があります。 (特に、これらのコミットされていないファイルがマージ プロセス中に変更される場合)
git-mergeを実行すると、コミットされていないファイルが大量に含まれやすくなります。紛争で後退するのが困難な状況にある。したがって、
2. パラメータgit-merge
を使用する場合は、コミットされていないファイルを使用することは強くお勧めできません。git-stash
コマンドを使用して、これらのコミットされていないファイルを一時的に保存し、競合を解決した後に使用することをお勧めします。git stash Pop
これらのコミットされていないファイルを復元します。
コマンド2.1
--no-commit
パラメーターを使用すると、マージ後にマージ結果のコミット ノードが生成されます。このパラメータは --no-commit
をオーバーライドできます。 --no-commit
パラメーターを使用すると、マージの失敗を防ぐためにマージが自動的に送信されなくなり、送信前にマージ結果を確認して変更する機会がユーザーに与えられます。 2.2
-e
および --no-edit
と -e
は、マージと送信が成功する前に、エディターを呼び出して、自動的に生成されたマージ情報をさらに編集するために使用されます。したがって、ユーザーは合併の結果をさらに解釈し、判断することができます。 --no-edit
パラメータを使用すると、自動的にマージされた情報を受け入れることができます (これは通常は推奨されません)。
-mノードの古いバージョンでは、ユーザーがマージ ログ情報を編集できない場合があります。パラメータを指定した場合 (後述)、
--edit
(または-e
) を使用します。は依然として便利ですが、これにより、エディタで-m
に含まれるコンテンツがさらに編集されます。
2.3--ff
は、早送りコマンドを指します。早送りモードを使用してマージする場合、新しいコミット ノードは作成されません。デフォルトでは、git-merge
は早送りモードを採用します。 早送りモードの詳細な説明については、私の別の記事「成功した Git ブランチ モデルの「早送りについて」セクション」を参照してください。
2.4
早送りモードが使用できる場合でも、新しいマージ ノードを作成します。これは、 がタグをマージするときのデフォルトの動作です。 2.5
現在の HEAD ノードが最新 (更新が最新のノードを指す) または早送りモードである場合を除きます。マージを使用できます。そうでない場合、マージは拒否され、失敗ステータスが返されます。 --log[=<n>]
および --no-log
##--log[=<n>] マージして送信すると、ブランチ名に加えて、最大 n 個のマージされたコミット ノードのログ情報も含まれます。
--no-log では、この情報はリストされません。
、
-n、
--no-statコマンド
--stat このパラメーターは、マージ結果の最後にファイルの差分のステータスを表示します。ファイル差異のステータスは、git 設定ファイルの merge.stat で設定することもできます。
対照的に、
-n、
--no-stat パラメーターでは、この情報は表示されません。
および
--no-squash
--squash マージが発生すると、現在のブランチと他のブランチの共通祖先ノードの後に他のブランチ ノードを追加し、他のブランチの最上位ノードまで圧縮します。ユーザーはレビュー後に送信して新しいノードを生成できます。
注 1: このパラメータは##注 2: このパラメータを使用した後の結果は次のようになります。現在のブランチに新しいノードをコミットします。このパラメーターは、Git Flow を使用する場合など、場合によっては非常に役立ちます (Git Flow については、「成功した Git ブランチ モデル」を参照してください)。関数ブランチが機能要件を開発しているとき、開発者はローカルで多数の要件を送信することがあります。また、意味のないノードは、develop ブランチにマージする必要がある場合、この長いノード リストの変更内容を表すために新しいノードを使用するだけで済みます。 #コマンドが活躍します。さらに、機能ブランチの複数の送信が簡単ではないが意味がある場合は、--no-ff と競合します
--no-ff--strategy=コマンドを使用する方が適切です。
および--no-squash
はまったく逆の効果があります。
2.8
-s
##-s マージ ノードに 1 つの親ノードのみが含まれる場合 (早送りを使用する場合など)モード)、再帰的戦略が使用されます (以下で紹介します)。
マージされたノードに複数の親ノードが含まれる場合 (早送りなしモードを使用している場合など)、タコ戦略 (後述) が使用されます。
在
- ■ 、戦略の特定のパラメータを指定します (後述)。
--verify-signatures、
--no-verify-signatures
は、マージされたノードに 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-stat2.12
-q および
--quize
はサイレントに動作し、マージの進行状況情報は表示されません。
2.13
-v--verbose
は、マージ結果の詳細情報を表示します。
--progress
および --no-progress
は、マージされた進捗情報を表示するかどうかを切り替えます。どちらも指定しない場合は、標準エラー発生時に接続端末にメッセージが表示されます。すべてのマージ戦略が進行状況レポートをサポートしているわけではないことに注意してください。
-S[<keyid>]
および --gpg-sign[=<keyid>]
GPG 署名。
-m <msg>
マージノード作成時に使用するコミット情報を設定します。
--log
パラメーターが指定されている場合、コミット ノードの短いログがコミット メッセージに追加されます。
--[no-]rerere-autoupdate
rerere は、記録された解像度を再利用する、記録されたソリューションを再利用することを意味します。これにより、ブロックの競合を解決する方法を Git に記憶させ、次回同じ競合が発生したときに Git が自動的に解決できるようにすることができます。
--abort
現在のマージ競合処理プロセスを放棄し、マージ前の状態の再構築を試みます。
外部ブランチをマージするときは、自分のブランチをクリーンな状態に保つ必要があります。そうしないと、マージ競合が発生します。多くの問題を引き起こします。
コミットをマージするときに無関係なファイルが記録されるのを避けるために、インデックスが指す HEAD ノードにコミットされていないファイルが登録されている場合、git-pull および git-merge コマンドは停止します。
通常、ブランチ マージではマージ ノードが生成されますが、いくつかの特殊なケースでは例外があります。たとえば、git pull コマンドを呼び出してリモート コードを更新する場合、ローカル ブランチにコミットがない場合は、マージ ノードを生成する必要はありません。この場合、マージ ノードは生成されず、HEAD は更新されたトップ コードを直接ポイントします。このマージ戦略は早送りマージです。
上記の早送りマージ モードに加えて、マージされたブランチはマージ ノードを介して現在のブランチに結び付けられます。マージ前の現在のブランチのノードと他のブランチの最上位ノード (両方とも親ノード)。
マージされたバージョンでは、コミット ノード、HEAD ノード、インデックス ポインターを含む、関連するすべてのブランチの変更の一貫性が保たれ、ノード ツリーが更新されます。これらのノード内のファイルが重複しない限り、これらのファイルへの変更はノード ツリー内で変更および更新されます。
これらの変更を明示的にマージできない場合、次のことが起こります:
MERGE_HEAD
Pointer Are他のブランチの上に配置されます。MERGE_HEAD
を記録します。ノード ツリー内のファイルには、マージ プログラムの結果が含まれています。たとえば、3 方向マージ アルゴリズムでは競合が発生する可能性があります。 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 つの親ノードがあります。
タグをマージすると、現時点で早送りモードが使用できる場合でも、Git は常にマージされたコミットを作成します。タグの情報には、投稿情報のテンプレートがあらかじめ設定されています。さらに、タグが署名されている場合、署名検出情報がコミット メッセージ テンプレートに追加されます。
マージ競合が発生すると、この部分は <<<<<<<
, # で終了します。 ##======== と
>>>>>>> を表します。
======= より前が自ブランチの状況、
======== より後が相手ブランチの状況です。 。
git merge --abort
が使用されます。 git add
を使用してインデックスに追加し、git commit
を使用してマージ ノードを生成します。 git mergetool
は、競合するマージを処理するためにビジュアル マージ ツールを呼び出します。 git diff
は、3 方向の差分 (3 方向マージで使用される 3 方向比較アルゴリズム) を表示します。 git log --merge -p <path>
は、HEAD
バージョンと MERGE_HEAD
バージョンの違いを表示します。 git show :1:ファイル名
共通祖先のバージョンを表示します。git show :2:ファイル名
現在のブランチの HEAD バージョンを表示します。git show :3 :ファイル名
相手のブランチのMERGE_HEAD
バージョンを表示します。 Git では、-s パラメーターを追加することでマージ戦略を指定できます。一部のマージ戦略には独自のパラメータ オプションもあります。これらのマージ戦略のパラメータ オプションを設定するには、-X<option>
を使用します。 (マージは git merge コマンドと git pull コマンドの両方で発生する可能性があるため、このマージ戦略は git pull にも適用されることを忘れないでください)。
3 方向マージ アルゴリズムは、2 つのブランチ (現在のブランチとプルダウンした別のブランチなど) の最上位ノードをマージする場合にのみ使用してください。このマージ戦略は 3 方向マージ アルゴリズムに従い、2 つのブランチの HEAD ノードと共通の子ノードが 3 方向マージを実行します。
もちろん、本当に気になるのはクロスマージ(十字併合)の状況です。いわゆるクロスマージとは、複数の共通の祖先ノードが存在する状況を指します。たとえば、2 つのブランチをマージする場合、2 つの共通の祖先ノードが存在する可能性が非常に高くなります。現時点では、それに応じてマージを実行できません。 3 方向マージ アルゴリズムに変換します (共通祖先ノードが一意ではないため)。これは、解決戦略がクロスマージの問題を処理する方法です。ここでは、「Git を使用したバージョン管理」への参照を示します:
クロスクロス マージの状況では、複数のマージ ベースが考えられます。解決戦略は次のように機能します: 可能なマージ ベースの 1 つを選択し、最善の結果を期待します。これは実際には、思っているほど悪くはありません。ユーザーがコードの別の部分で作業していることが判明することがよくあります。この場合、Git は、既に存在する一部の変更を再マージしていることを検出し、重複する変更をスキップして競合を回避します。または、これらが競合を引き起こすわずかな変更である場合、少なくとも開発者にとって競合は簡単に処理できるはずです
これは簡単な翻訳です: クロスマージの場合、複数のマージ リファレンス ポイント (共通の祖先ノード) が存在します。解決戦略は次のように機能します: 可能なマージ リファレンス ポイントの 1 つを選択します。これが最もマージされた参照点であることが期待されます。良い結果が得られます。これは実際のところ、思っているほど悪くはありません。通常、ユーザーはコードのさまざまな部分を変更しますが、その場合、多くのマージ競合は実際には冗長で反復的になります。解決を使用してマージすると、生成された競合の処理が容易になり、実際にコードが失われるケースはほとんどありません。
2 つのブランチをマージする場合は、3 方向マージ アルゴリズムのみを使用してください。解決とは異なり、クロス マージの場合、このマージ メソッドは再帰的に呼び出されます。共通の祖先ノードの後の 2 つのブランチの異なるノードから開始して、3 方向マージ アルゴリズムが再帰的に呼び出されてマージされます。競合が発生した場合は、その後、ファイルのマージは続行されなくなり、競合が直接スローされます。競合のない他のファイルは最上位ノードまで実行されます。さらに、このアプローチでは、ファイル名の変更を伴う操作を検出して処理できます。これは、git のマージおよびコードのプルのデフォルトのマージ アクションです。
再帰的マージ戦略には次のパラメータがあります:
このパラメータは、競合が発生したときに現在のブランチのバージョンが自動的に使用されるように強制します。このマージ方法では問題は発生せず、git でも他のブランチのバージョンに含まれる競合内容をチェックせず、他のブランチの競合内容を破棄します。
は私たちのものとはまったく逆です。
彼らのパラメータと私たちのパラメータはどちらも、バイナリ ファイルの競合をマージするのに適しています。
このパラメータを使用すると、git merge-recursive
重要でない行 (関数など) の括弧の欠落を避けるために、余分な時間を費やします)。現在のブランチと他のブランチの間のバージョン ブランチの分離が非常に大きい場合は、このマージ方法を使用することをお勧めします。
diff-algorithm=[patience|minimal|histogram|myers]
情報git merge-recursive
別の比較アルゴリズムを使用する。
ignore-space-change
、ignore-all-space
、ignore-space-at-eol
指定されたパラメータに従ってスペースの競合を処理します。
名前変更なし
名前変更の検出をオフにします。
subtree[=<path>]
このオプションは、サブツリー マージ戦略の高度な形式であり、2 つのノード ツリーをマージするプロセスを推測します。 . 入居方法。違いは、指定されたパスがマージの開始時に削除されるため、サブツリーを検索するときに他のパスが照合できることです。 (サブツリー マージ戦略の詳細については、以下を参照してください)
このマージ方法は 3 つ以上のブランチに使用されますが、競合により手動マージが必要な場合はマージが拒否されます。このマージ方法は、複数のブランチをバンドルするのにより適しており、複数ブランチのマージのデフォルトのマージ戦略でもあります。
このメソッドは任意の数のブランチをマージできますが、ノード ツリーのマージ結果は常に現在のブランチの競合部分になります。この方法は、古いバージョンを置き換える場合に非常に効率的です。このメソッドは、再帰的戦略におけるパラメータとは異なることに注意してください。
サブツリーは、再帰戦略の修正バージョンです。ツリー A とツリー B をマージするとき、B が A のサブツリーである場合、B は同じノードを読み取るのではなく、まず A のツリー構造に一致するように調整します。
3 方向マージ戦略 (デフォルトの再帰戦略を参照) を使用する場合、現在のブランチと他のブランチの両方でファイル (またはコード行) が変更された場合、その後、ブランチの 1 つにロールバックします。その後、このロールバックの変更が結果に反映されます。この点で混乱する人もいるかもしれません。これは、マージ プロセス中、git は 2 つのブランチのすべてのノードではなく、2 つのブランチの共通の祖先ノードと HEAD ノードのみに焦点を当てるためです。したがって、マージ アルゴリズムはロールバックされた部分を unchanged とみなし、マージされた結果が他のブランチの変更された部分になります。
私は常に Git が非常に優れたバージョン管理ツールであると信じてきましたが、社内の多くの人が Git を使いにくいと感じています。この状況の主な理由は、以前の Subversion の使用によってもたらされた慣性が新しいテクノロジーの受け入れに影響を与えていることですが、その一方で、多くの人が GUI クライアントを通じてのみ Git を使用していることです。長い間、ほとんどの人は GUI を使用するほうが簡単に始めることができると考えてきましたが、実際にはこれには疑問があります。私の個人的な経験によると、GUI を使用すると慣性が発生し、ボタンをいくつかクリックするだけで操作が完了することが多いため、多くの人が Git コマンドを学習するのは時間とエネルギーの無駄であると考えています。しかし、実際には、Git のコマンドや概念を明確に理解していないと、これらの単純なボタンを使用すると、実際には多くの問題が発生します。多くの人は、ボタンをクリックした後に何が起こるかわかりません。また、GUI が賢すぎるため、同じボタンを使用することはできません。クリック イベントは、さまざまなパラメータを持つコマンドに対応する場合があります。結局のところ、本当に傷つくのは、何が問題なのか全く分からない可哀想なユーザーです。
全文の内容に基づいて、Git を使用する際に個人が従う規則のいくつかを要約します。いわゆる合意とは、強制的ではない自発的な行為を指します。これらの規則に従わなくても問題が発生することはありませんが、これらの規則に従うと、Git を使用する際の問題が軽減され、効率が向上する可能性があります。
推奨学習: 「Git 学習チュートリアル 」
以上がgit-merge の詳細な分析 (整理および共有)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。