レッスン 22 · 歴史と統合
ローカルコミットの並べ替え、スカッシュ、書き直し、削除
5 つの大まかなプライベート コミットを 2 つのクリーンなコミットに変換します。依存する修正を移動し、メッセージを書き直し、ステップを折りたたんで潰し、ノイズのみを削除し、結果に意図したとおりのファイルが含まれていることを確認します。
- レベル: 上級者向け
- 6 分で読みました
- 7 分の動画
- 更新されました
- このレッスンの前に: 未公開の作品を新しいベースにリベースする
このブラウザに進行状況が保存されました。
再生すると、YouTube からビデオが読み込まれます (プライバシー強化モード)。
何を学ぶか
- 再生プランを読み取ります。最も古いステップが最初に、上から下に適用されます。
- 適切なアクションを選択してください: 言い直し、スカッシュ、修正、削除。
- 依存するステップを中断せずにステップを移動します。
- その後、新しいコミット、ファイル、レスキュー ブランチを確認します。
始める前に
ブランチ private/signup-polish には、コミット M の上に、コンピューター上にのみ存在するコミットが 5 つあります。ワーク ツリーはクリーンで、rescue/before-polish は 5 番目のコミットを指します。順番に、古いものから順に:
| ステップ | 専念 | 何をするのか |
|---|---|---|
| C1 | 特技: サインアップの下書きを追加 | サインアップフォームを追加します |
| C2 | ドキュメント: サインアップレビューの説明 | docs/replay-a.mdを追加します |
| C3 | ドキュメント: 検証について説明する | docs/replay-b.mdを追加します |
| C4 | 修正してください!特技: サインアップの下書きを追加 | フォームのラベルを修正します |
| C5 | 雑用: 一時的なメモ | docs/temporary-review.mdを追加します |
すべてがローカルであり、無料プランです (GitTree はサインインを要求します)。ホスティング アカウント、プロバイダー、インターネットはありません。すべてのアイデンティティは架空のものです (example.com)。このレッスンを実際のプロジェクトで決して実行しないでください。また、他の人がすでに持っているコミットを書き換えないでください。
変更は、GitTree で行うか、ネイティブ Git コマンドを使用して行います。両方を同じコピーに行うことはできません。結果の読み取りは常に安全です。メニュー ラベルは GitTree 2.0 独自の文字列から取得され、ネイティブ コマンドは使い捨てコピーの Git 2.43 で実行されました。 GitTree ステップは macOS、Windows、または Linux で実行されませんでした。
概念と状態の効果
インタラクティブなリベースは計画であり、並べ替えゲームではありません。 Git は、リストされたコミットをリストの上から下に 1 つずつベースで再生するため、最も古いステップが最初に表示されます。各アクションは、Git に 1 つのステップで何を行うかを指示します。
- Pick はコミットをそのまま保持します。
- Reword はコンテンツを保持し、新しいメッセージを作成できるようにします。
- Squash はコミットをその上に保持されているコミットに折りたたんで、1 つの結合されたメッセージを作成できるようにします。
- Fixup もそれを組み込みますが、それ自体のメッセージは破棄されます。
- Drop はコミットの変更を完全に残します。
順序が重要です。別のステップに依存するステップ (ここではラベル修正には C1 からのフォームが必要です) はその下にある必要があります。エディターではそれを上に移動できますが、競合が発生してリプレイが停止します。 GitTree も、Git が実行できないプラン、つまり、すべてのコミットを削除するプラン、折り畳まれる上に何もないスカッシュ、および空のメッセージを拒否します。
親が変更されるため、再生されたすべてのコミットには新しい ID が取得されます。このブランチのみが書き換えられます。レスキューブランチは古い5人を保管しています。すでにリモート上にあるコミットには「リモート上」とマークが付けられ、それらを書き換えるには明示的な確認が必要です。この教訓は決してそれを裏付けるものではありません。
構築する計画では、5 つのコミットが 2 つに変換されます。
| ステップ | 専念 | アクション | 結果 |
|---|---|---|---|
| 1 | C1 | 言い直し | 特技: ローカルのサインアップ フォームに記入する |
| 2 | C4 | 修正 | ステップ1に折りたたまれます |
| 3 | C3 | ピック | 保管されています。スカッシュターゲット |
| 4 | C2 | スカッシュ | ドキュメント: サインアップのレビューと検証について説明します |
| 5 | C5 | ドロップ | 消えた |
正確なプロジェクトの状態を準備する
レッスン 18 で残したプロジェクトの別の通常のコピーから開始します。元の gittree-features はそのままにしておきます。新しいブランチ上に以下の 5 つのコミットを一度に 1 ファイルずつビルドし、それぞれの完全な本文を名前付きステップでのみ保存します。
完全なファイル入力
以下のフェーズでのみ保存します。これらは、最後に改行を含む完全な 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>
<section aria-labelledby="signup-title">
<h2 id="signup-title">Try the demo form</h2>
<form id="signup-form" novalidate>
<label for="demo-email">Demo email</label>
<input id="demo-email" name="email" type="email" autocomplete="off" aria-describedby="signup-hint">
<p id="signup-hint">Use a fictional example.com address. Nothing is sent.</p>
<button type="submit">Check the address locally</button>
<p id="signup-result" role="status"></p>
</form>
</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>docs/replay-a.md — DOC_A
# Local signup review
Review the label and hint together.docs/replay-b.md — DOC_B
# Local validation review
No address leaves this demonstration.Index.html — SIGNUP_LABEL
<!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>
<section aria-labelledby="signup-title">
<h2 id="signup-title">Try the demo form</h2>
<form id="signup-form" novalidate>
<label for="demo-email">Fictional email address</label>
<input id="demo-email" name="email" type="email" autocomplete="off" aria-describedby="signup-hint">
<p id="signup-hint">Use a fictional example.com address. Nothing is sent.</p>
<button type="submit">Check the address locally</button>
<p id="signup-result" role="status"></p>
</form>
</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>docs/temporary-review.md — DOC_NOISE
Temporary rehearsal note, deliberately dropped.GitTreeで
Command+Shift+P (Ubuntu では Ctrl+Shift+P) でパレットを開きます。コミットに対するアクションでは、そのコミットの右クリック メニューを使用します。
- 次のセクションで示すように、
private/signup-polishをチェックアウトしてクリーンにして、5 つのコミットとレスキュー ブランチをビルドします。 M と 5 人の被験者に注目してください。 - 5 のすぐ下のコミットである M を右クリックし、Edit History → Interactive Rebase of the Commits Above… を選択します。エディターが開き、古いものから順に 5 つのプライベート ステップが表示されます。
- Options for this rebase では、Arrange fixup!, squash! and amend! commits を含む 3 つのオプションをすべてオフのままにします。フィックスアップを自分で移動します。
- C4 行にフォーカスして Alt+↑ を 2 回押し、次に C3 行にフォーカスして Alt+↑ を 1 回押します。順序は C1、C4、C3、C2、C5 になります。フォーカスされた行で p、r、e、s、f、または d を押すと、ピック、リワード、編集、スカッシュ、フィックスアップ、またはドロップが設定されます。
- C1 を Reword に設定し、メッセージ フィールドに
feat: complete the local signup formと入力します。 C4 を Fixup に設定します。 - C3 を Pick のままにし、C2 を Squash に設定します。 Squashed commits の下のグループ「2 commits into docs: Explain validation」には、結合されたメッセージが表示されます。これを
docs: explain signup review and validationに置き換えます。 - C5 を Drop に設定します。すべての行と結合されたメッセージをもう一度読みます。何も「リモート上」とマークされていないため、確認は必要ありません。
- Start Rebase を 1 回選択して待ちます。停止した場合は、バナーを使用して続行してください。計画全体を再度開始しないでください。
- 2 つの新しいコミット、ページ内のラベルの修正、両方のドキュメント、および一時的なメモがないことを確認します。
rescue/before-polishを維持し、ワークツリーをクリーンなままにしておきます。
コース内のすべての通常のコミット: Summary は指定された件名、Description は空、オプション Amend Previous Commit、Skip Hooks、Add Signed-off-by、Different Author、Push After Commit、および Allow Empty Commit はオフのままです。
ターミナル内
新しいブランチに 5 つのコミットをビルドし、各ステップで完全な本体を保存します。
git switch --create private/signup-polishサインアップを index.html として保存し、次のようにします。
git add -- index.html
git commit --quiet -m "feat: add signup draft"DOC_A を docs/replay-a.md として保存し、次のようにします。
git add -- docs/replay-a.md
git commit --quiet -m "docs: explain signup review"DOC_B を docs/replay-b.md として保存し、次のようにします。
git add -- docs/replay-b.md
git commit --quiet -m "docs: explain validation"SIGNUP_LABEL を index.html として保存し、次のようにします。
git add -- index.html
git commit --quiet -m "fixup! feat: add signup draft"DOC_NOISE を docs/temporary-review.md として保存し、次のようにします。
git add -- docs/temporary-review.md
git commit --quiet -m "chore: temporary note"古いチップを保護し、古いものから順に範囲をリストします。
git branch rescue/before-polish
BASE_SHA="$(git rev-parse HEAD~5)"
git log --reverse --format=%s "$BASE_SHA"..HEADここで対話型リベースを開始します (-i は --interactive の短縮形です)。 Git により、ToDo リストが表示されたエディターが開きます (ID は異なります)。
git rebase --interactive --no-autosquash --no-update-refs --no-autostash "$BASE_SHA"pick 1a2b3c4 feat: add signup draft
pick 2b3c4d5 docs: explain signup review
pick 3c4d5e6 docs: explain validation
pick 4d5e6f7 fixup! feat: add signup draft
pick 5e6f708 chore: temporary note各行の独自の ID を保持しながら、プランに 5 行を書き換えて保存します。
reword 1a2b3c4 feat: add signup draft
fixup 4d5e6f7 fixup! feat: add signup draft
pick 3c4d5e6 docs: explain validation
squash 2b3c4d5 docs: explain signup review
drop 5e6f708 chore: temporary noteその後、Git はエディターをさらに 2 回開きます。言い換える場合は、メッセージを feat: complete the local signup form に置き換えてください。スカッシュの場合は、両方のメッセージが表示されます。これらを 1 行 docs: explain signup review and validation に置き換えます。結果を確認します。
git rev-list --count "$BASE_SHA"..HEAD
git log --reverse --format=%s "$BASE_SHA"..HEAD
git status --short2
feat: complete the local signup form
docs: explain signup review and validationステータスは空です。 index.html は SIGNUP_LABEL です。両方のドキュメントが存在しますが、docs/temporary-review.md は存在しません。
1行目にsquashを入れるとGitはerror: cannot 'squash' without a previous commitで即停止します。 git rebase --edit-todo と git rebase --continue でリストを修正するか、git rebase --abort で終了します。 --autosquash を使用すると、Git が fixup! コミットの移動とアクションを実行します。このレッスンでは計画を表示するためにオフにします。
結果
Where you end: M より上の 2 つの書き換えられたコミット、「feat: ローカルのサインアップ フォームに記入する」と「docs: サインアップのレビューと検証について説明する」。ページにはラベルが修正されており、両方のドキュメントが存在しますが、一時的なメモは存在しません。古い 5 つのコミットはレスキュー ブランチによって保持され、ワーク ツリーはクリーンになります。
よくある間違い
- Drop を使用して必要なコミットを非表示にします。その変化は新しい歴史にはまったく含まれていません。
- 修正をコミットの上に移動すると、修正されます。
- 最初のステップを潰します。そのステップより上には折りたたむものはありません。
- 最初に結果を確認するのではなく、完了後に計画を再度開始します。
何か問題が発生した場合
開始する前に、Cancel はブランチをそのままにしておきます。 GitTree がエディタを開いてからブランチが変更されたと言っている場合は、エディタを閉じて再度開きます。リベースが停止した場合は、競合またはメッセージを修正してバナーから続行するか、意図的に中止します。完了したら、何かを復元する前に、rescue/before-polish と比較してください。
理解度を確認してください
各質問に答えてから、その理由を読みましょう。 「必須」とマークされた質問は、レッスンの完了にカウントされます。
6 個中 0 個が正解です
必須の質問に正しく答えると、レッスンを完了できます。
このブラウザで確認しました。
練習する
プラン C1、C4、C3、C2、C5、および生き残る 2 つのメッセージについて説明します。古い範囲 5、新しい範囲 2、予期されるファイル、およびメモがないことを確認してください。次に、C4 を C1 の上に移動したり、ステップ 1 を潰したりできない理由を、実行せずに予測します。
あなた自身の確認: サイトはあなたのコンピュータを認識できません。
レッスンを完了するには、必須の質問に正しく答え、実践的な演習を確認してください。
要約
- 再生プランには順序と依存関係があります。
- Squash は、結合できるように両方のメッセージを保持します。 fixup はそれ自体を破棄します。
- ドロップすると変更自体が削除されるため、実際のノイズのみをドロップします。
関連している
用語集の用語の紹介
言い換え — إعادة صياغة;スカッシュ — ضمّ;修正 — 修正 — 修正。ドロップ — ヤスデ;リプレイプラン — خطة إعادة تطبيق.
ビデオトランスクリプト
ビデオのナレーションが次々と流れます。
トランスクリプトを表示する
- 5 つの大まかなコミットが 2 つのクリーンなコミットになります。 safely.
- インタラクティブなリベースは計画です。 ステップ、古い順。
- Git はリストを上から下に再生します。 基地。
- 各ステップにはアクションが与えられます: 選択、言い換え、 スカッシュ、フィックスアップ、またはドロップ。
- まず、5 つのプライベート コミットと 1 つのコミットをビルドします。 救助支店。
- 3つは実際の作業です。 1つは修正で、もう1つは 一時的なノイズです。
- その下のコミットを右クリックし、 編集履歴を開きます。
- コミットの対話型リベースを選択します 以上。
- エディターには、最も古いものから 5 つのステップがリストされます。 まず。
- 3 つのオプションはすべてオフのままにしておきます。 We will move 自分たちで修正します。
- 修正はコミットの直後に行われます それは修正されます。上に2回動かします。
- 次に、検証メモを上に移動します。 レビューメモ。
- 順番は 1、4、3、2、 5つ。
- 最初のステップを Reword に設定し、次のように書きます。 新しいメッセージ。
- 修正ステップを修正に設定します。そのメッセージ 捨てられる。
- 検証メモを保管し、 ノートを見直してください。
- Squash には両方のメッセージが表示されます。一つ書いてください ペアへのメッセージ。
- 一時メモを削除します。その変化は 生き残れない。
- すべての行をもう一度読みます。上には何もありません リモート。
- Start Rebaseを一度選択して、それを待ちます to finish.
- グラフには、上に 2 つのコミットがあります。 base.
- Both have new IDs.古い5人は rescue branch.
- ページを開くと、ラベルの修正が行われています。の ノイズが消えました。
- ターミナルでも同じプランが表示されます。 git rebase -i.
- Git が Todo リストを開きます。 Oldest first, all 選択するように設定します。
- 計画の行を書き換えます: reword, フィックスアップ、ピック、スカッシュ、ドロップ。
- Git は 2 つのメッセージを要求します。一つ書いてください line for each.
- ベースより上のコミットを数えます: 2。
- 主題を列挙します。この二人が私たちです と書きました。
- ステータスは空で、一時的なメモは 消えた。
- 入力を変更します。スカッシュを 最初のステップ。
- その上には折りたためるものが何もないので、 Git refuses.
- または、フィックスアップをコミットの上に移動します。 リプレイは競合により停止します。
- 停止した場合は、修正して続行します。または 中止され、何も変わりません。
- レスキューブランチはまだあなたのものを保持しています original five commits.
- 他の人のコミットを決して書き換えないでください すでに持っています。
- 練習: 計画とそのステップの理由を説明する スカッシュにはなれない。
- 次に、マージまたは rebase stops.