レッスン 23 · 回復
マージとリベースの競合を解決する
マージとリベースで競合する同じ見出しを解決し、「私たちのもの」と「彼らの」がそれらの間で入れ替わる理由を確認し、意図的に結合された 1 つの結果を保存し、どちらの人のアイデアも失わずに各操作を完了します。
- レベル: 中級者
- 6 分で読みました
- 7 分の動画
- 更新されました
- このレッスンの前に: 分岐した履歴を持つブランチをマージする, 未公開の作品を新しいベースにリベースする
このブラウザに進行状況が保存されました。
再生すると、YouTube からビデオが読み込まれます (プライバシー強化モード)。
何を学ぶか
- 基地、現在の側、そして来る側の本当の対立を読んでください。
- マージとリベースの間で「私たち」と「彼ら」が入れ替わる理由を説明してください。
- 意図的な解決策を 1 つ書き、それを解決済みとしてマークします。
- 操作を続行し、中途半端な作業がないか確認してください。
始める前に
2 人のチームメイトがページの同じ行を変更しました。 conflict/sara に、サラはヒーローの見出しを「自信を持って変更を確認する」に変更しました。 conflict/omar で、Omar は同じ行を「保存された各変更を理解する」に変更しました。どちらのブランチもコミット M から始まり、その見出しは「作業を明確に見てください。」であり、各ブランチには 1 つのコミットがあります。この分岐の同一のコピーを 2 つ作成します。1 つはマージ用 (gittree-conflict-merge)、もう 1 つはリベース用 (gittree-conflict-rebase) です。どちらの場合も、conflict/sara はチェックアウトされており、ワーク ツリーはクリーンです。マージまたはリベースは実行されていません。
すべてがローカルであり、無料プランです (GitTree はサインインを要求します)。ホスティング アカウント、プロバイダー、インターネットはありません。すべてのアイデンティティは架空のものです (example.com)。このレッスンを実際のプロジェクトで実行しないでください。
変更は、GitTree 内で行うか、ネイティブ Git コマンドを使用して行います。同じコピー内で両方を行うことはできません。結果の読み取りは常に安全です。メニュー ラベルは GitTree 2.0 独自の文字列から取得され、ネイティブ コマンドは使い捨てコピーの Git 2.43 で実行されました。 GitTree ステップは macOS、Windows、または Linux で実行されませんでした。
概念と状態の効果
コンテンツの競合は、Git が単独で 1 つの結果を選択できないことを意味します。つまり、両側が同じ行を別々に変更しました。 Git は停止し、ファイルの 3 つのバージョンをインデックスに保持します。ステージ 1 は共通ベース、ステージ 2 は「私たちの」、ステージ 3 は「彼らの」です。また、ワークツリー内のファイルに競合マーカーも書き込まれます。エディターでマーカーを削除しても、Git では何も解決されません。ファイルは、結果を保存してステージングする場合にのみ解決され、ステージ 0 に戻ります。
「私たち」と「彼ら」は立場であって、人ではありません。マージでは、Sara のブランチにいることになるため、私たちのバージョンは Sara のバージョン (現在の側) で、彼らのバージョンは Omar のバージョン (受信側) になります。 Sara を Omar にリベースする場合、Git はまず Omar のブランチに移動し、次に Sara のコミットを再生します。そのため、私たちのバージョンは Omar のバージョン (リベース先のブランチ) で、彼らのバージョンは Sara のコミットです。 GitTree は各名前の横にロールを出力するため、マージの場合は「(current)」と「(incoming)」、リベースの場合は「(rebaseing on)」と「(your commit)」を覚えておく必要はありません。
正しい結果が片側であることはほとんどありません。ここで意図されている解決策は「自信を持ってそれぞれの変更を確認してください。」であり、サラのセリフでもオマールのセリフでもありません。ページの 1 行おきを元の状態のままにしておきます。ファイルを解決済みとしてマークすると、結果が段階的に表示されます。 「続行」は、マージ コミットを終了するか、Omar のコミットで Sara のコミットを再作成する別のステップです。
操作が停止している間、ブランチは操作が終了した場所にあり、ファイルは競合します。サーバーには何も届きません。
正確なプロジェクトの状態を準備する
分岐を 1 つ作成し、それを 2 回コピーします。レッスン 18 で残したプロジェクトの別の通常のコピーから開始し、元の gittree-features はそのままにしておきます。ページのバージョンは以下のとおりです。 MERGED は共有ベース、SARA と OMAR は 2 つの競合するバージョン、RESOLVED は保存する結果です。
完全なファイル入力
以下のフェーズでのみ保存します。これらは、最後に改行を含む完全な UTF-8/LF 本文です。 Markdown フェンスは決して貼り付けないでください。変更されていない実行可能ファイルは、名前付き入力を継承します。別のバリアントのバージョンでオリジナルを上書きしてはなりません。
Index.html — マージ済み
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">See your work clearly.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>インデックス.html — サラ
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Review changes with confidence.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>インデックス.html — オマール
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Understand each saved change.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>Index.html — 解決済み
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Review each change with confidence.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>GitTreeで
Command+Shift+P (Ubuntu では Ctrl+Shift+P) でパレットを開きます。名前付きブランチに対するアクションには、そのブランチの右クリック メニューが使用されます。
- 次のセクションで示すように、2 つのコピーを構築します。
conflict/saraをチェックアウトして gittree-conflict-merge を開きます。 conflict/omarを右クリックして、Merge conflict/omar into conflict/sara を選択します。 Record it as で Always a merge commit を選択します。ダイアログは「1 つのファイルに競合があるため停止します」と警告します。 Mergeを選択します。マージは停止しますが、これは予期された結果です。- バナーには「競合/omar を競合/sara にマージします」と「競合 1 件」が表示されますが、Continue はまだ利用できません: 「最初に 1 件の競合を解決してください」。 Resolveを選択します。
- Conflicted files から
index.htmlを開きます。 2 つの面 conflict/sara (current) と conflict/omar (incoming) を読み取り、Show Base を使用して Base (common ancestor) を読み取ります。 - Edit Output を選択し、競合する見出しを
Review each change with confidence.に置き換え、1 行おきにします。次に、Save and Mark Resolved を選択します。マーカーを削除してファイルを閉じるだけでは十分ではありません。 - バナーに戻り、Continue を選択します。メッセージが提供された場合は、提案されたメッセージをそのままにしておきます。マージが完了するまで待ちます。新しいコミットには 2 つの親があります。
conflict/saraをチェックアウトして gittree-conflict-rebase を開きます。conflict/omarを右クリックして、Rebase conflict/sara onto conflict/omarを選択します。 Options for this rebase の下のオプションはオフのままにして、Rebase conflict/sara を選択します。それは衝突で止まります。- Resolve を選択し、
index.htmlを開きます。サイドは conflict/omar (rebasing onto) と conflict/sara (your commit) になり、役割が入れ替わりました。同じように Edit Output → Save and Mark Resolved、次に Continue を実行します。 - 両方のコピーを確認します。ファイルは解決済みであり、競合するファイルは残っておらず、バナーも表示されていません。 2 つの結果を離して、押し込まないでください。
コース内のすべての通常のコミット: Summary は指定された件名、Description は空、オプション Amend Previous Commit、Skip Hooks、Add Signed-off-by、Different Author、Push After Commit、および Allow Empty Commit はオフのままです。
ターミナル内
レッスン 18 の結果の別のクリーン コピー:
git switch --create conflict/sara
BASE_SHA="$(git rev-parse HEAD)"SARA を index.html として保存し、次のようにします。
git add -- index.html
git -c user.name="Sara Lindqvist" -c user.email=sara@example.com commit --quiet -m "feat: Sara clarifies the hero"
git switch --quiet --create conflict/omar "$BASE_SHA"OMAR を index.html として保存し、次のようにします。
git add -- index.html
git -c user.name="Omar Haddad" -c user.email=omar@example.com commit --quiet -m "feat: Omar explains the hero"
git switch --quiet conflict/saraBASE_SHA は、競合するコミットの前の M です。この分岐のクリーン コピーを 2 つ作成します。1 つはマージ用、もう 1 つはリベース用です (cd .. && cp -R gittree-features gittree-conflict-merge && cp -R gittree-features gittree-conflict-rebase)。マージコピーでは次のようになります。
git merge --no-ff --no-edit conflict/omar
git ls-files --unmerged
git show :2:index.html
git show :3:index.htmlマージは終了コード 1 で停止し、git ls-files --unmerged にはステージ 1、2、3 の 3 つのエントリがリストされます。git show :2:index.html は Sara のバージョン (私たちのバージョン)、:3: は Omar のバージョン (彼らのバージョン) です。 :1: がベースです。 RESOLVED を index.html として保存し、次のようにします。
git add -- index.html
git -c core.editor=true merge --continue
git ls-files --unmerged
git status --short最後の 2 つのコマンドは何も出力しません。変更されていないリベース コピーでは次のようになります。
git rebase conflict/omar
git show :2:index.html
git show :3:index.htmlリベースが停止します。これで、:2: がオマールのバージョンになり、:3: がサラのバージョンになり、役割が入れ替わりました。 RESOLVED を index.html として保存し、次のようにします。
git add -- index.html
git -c core.editor=true rebase --continue
git ls-files --unmerged
git status --short両方のファイルが RESOLVED になり、マージが解除されたものは何もありません。 core.editor=true は、この 1 つのコマンドに対する既存のコミット メッセージのみを受け入れます。エディタの設定は変更されません。停止したオペレーションを解決せずに終了するには、git merge --abort または git rebase --abort を使用します。
結果
Where you end: マージ コピーには 2 つの親と結合された見出しを持つ新しいコミットがあります。リベース コピーには、同じ結合された見出しを持つ Omar のコミットで再作成された Sara のコミットが含まれています。どちらの場合も、index.html は RESOLVED に等しく、競合エントリは残っておらず、操作は終了し、ステータスはクリーンです。
よくある間違い
- 「私たちの」とは常に独自の機能を意味すると仮定します。これは Git がどちらの側に立っているかを意味し、それは操作によって変わります。
- 両方のバージョンとファイルの残りの部分を読み取る前に、片側を完全に取得 (「Take All」) します。
- 競合マーカーを削除しますが、ファイルを保存して解決済みとしてマークすることはありません。
- すでに終了したマージまたはリベースを繰り返す。
何か問題が発生した場合
停止が間違っていると思われる場合、バナーの Abort… は操作が開始された状態を復元し、それまでに行われた解決策を破棄します。 GitTree は最初に回復スナップショットを保持します。編集中にファイルが変更された場合は、古い保存を強制するのではなく、Compare と Use as Output の選択肢を使用してください。下書きを置き換える前に、下書きのコピーを保管してください。
理解度を確認してください
各質問に答えてから、その理由を読みましょう。 「必須」とマークされた質問は、レッスンの完了にカウントされます。
6 個中 0 個が正解です
必須の質問に正しく答えると、レッスンを完了できます。
このブラウザで確認しました。
練習する
git show :2:index.html と git show :3:index.html を使用して両方のオペレーションのステージ ロールを証明し、同じ解決済みファイルを保存して各オペレーションを終了します。両方のコピーで「ours」を盲目的に取得した場合、ページに何が残るかを予測します。
あなた自身の確認: サイトはあなたのコンピュータを認識できません。
レッスンを完了するには、必須の質問に正しく答え、実践的な演習を確認してください。
要約
- 私たちと彼らの役割は作戦によって異なります。
- まず保存して解決済みとしてマークしてから、続行します。
- その後、ファイル全体と動作状態を確認してください。
関連している
用語集の用語の紹介
紛争 - 紛争;ベース — ベース。私たちのもの — ナオミ。彼らのもの — سختهم;解決する — 解決する。
ビデオトランスクリプト
ビデオのナレーションが次々と流れます。
トランスクリプトを表示する
- 競合はエラーではありません。それは あなただけが答えられる質問。
- 2 人が同じ行を変更しました 同じファイル。
- サラは見出しを 1 つ書きました。 Omar wrote もう一つ。どちらも同じページから始まりました。
- Git はどの行が勝つかを推測できないため、 立ち止まって尋ねます。
- まず、Sara と Omar のブランチを構築します。 そして同一のコピーが 2 つあります。
- 最初のコピーではマージします。 In the second, we rebase.
- Sara のブランチでマージ コピーを開きます。
- Omar のブランチを右クリックし、そのブランチを選択します Merge command.
- ダイアログにはすでに警告が表示されています: これは停止します 1 つのファイルに競合があります。
- 「常にマージコミット」を選択し、「マージ」を選択します。 一度。予想通り止まります。
- バナーには 1 つの競合が表示されます。 Continue is まだ利用できません。
- [解決] を選択し、index.html を開きます。
- 2 つの側面: Sara のブランチは現在、 オマールが到着します。
- Show Base は共通の祖先を明らかにします。 変更前のページ。
- 次に出力を編集します。見出しを次のように置き換えます 意図的な一行。
- 保存して解決済みとしてマークします。 Only now does Git ファイルを解決済みとして扱います。
- バナーに戻り、「続行」を選択します。の マージが終了します。
- 新しいコミットには 2 つの親があり、 結合された見出し。
- これで、リベースのコピーもサラのものになります 枝。
- Omar のブランチを右クリックし、リベースします サラのブランチです。
- オプションをオフのままにし、一度リベースします。それ 競合で停止します。
- ラベルを見てください。現在、オマールの支店は the one we rebase onto.
- Sara のコミットが再生されます。 役割が入れ替わりました。
- 同じ解像度: 出力を編集して保存 解決済みとしてマークし、続行します。
- Sara のコミットは上に再作成されます オマールのもの、同じ見出しです。
- ターミナルで、マージされていないエントリをリストします。 停止したマージの。
- ステージ 2 は私たちのものです。サラのヘディングです。ステージ 3 つは彼らのもので、オマールのものです。
- 停止したリベースのステージ 2 と 3 その逆です。
- 修正後は何もマージが解除されず、 ステータスは空です。
- マージ コピーのチップには 2 つの親があります。の rebase コピーのヒントには 1 つあります。
- 入力を変更します。マーカーを削除し、 保存しますが、解決済みとしてマークしません。
- Git にはまだ 3 つのステージが表示されるため、続行します 利用できないままになります。
- 立ち往生?中止するとブランチが元の場所に戻ります the operation began.
- GitTree は最初に回復スナップショットを保存します。 したがって、中止しても安全です。
- 決して自分の前の一方からすべてを奪ってはいけません 両方のバージョンを読んでください。
- 練習: 両方の舞台での役割を証明する コピーして、両方を終了します。
- 次に、操作を続行、スキップ、または中止します それは止まってしまった。