レッスン 31 · 回復
孤立した仕事を続けて孤立した歴史を始める
切り離された HEAD を離れる前に、そのコミットに名前を付けてから、別のコピーで孤立したブランチを開始し、何が削除され、何が保持されるかを確認します。
- レベル: 中級者
- 5 分で読みました
- 5 分の動画
- 更新されました
- このレッスンの前に: 機能ブランチを作成し、使い捨ての ref のみをリタイアします, reflog で失われたコミットを見つける
このブラウザに進行状況が保存されました。
再生すると、YouTube からビデオが読み込まれます (プライバシー強化モード)。
何を学ぶか
- 付着した頭、切り離された頭、そしてまだ生まれていない頭を区別します。
- 接続解除されたコミットにブランチを配置して、到達可能な状態を維持します。
- 孤立したブランチが追跡されたファイル、追跡されていないファイル、および古いブランチに対して何を行うかを予測します。
- ローカルの変更によって引き起こされたチェックアウトの拒否を読み取ります。
始める前に
レッスン 18 の結果 M の 2 つの使い捨てコピー。最初のコピーでは、ブランチではなくコミット M 自体をチェックアウトし、そこに小さなスタイルシート変更を加え、それを保持したいとします。 2 番目の例では、main をタッチせずに、ドキュメントのみのブランチに関するまったく新しい関連性のない履歴が必要です。
すべてがローカルであり、無料プランです (GitTree はサインインを要求します)。ホスティング アカウント、プロバイダー、インターネットはありません。すべてのアイデンティティは架空のものです (example.com)。このレッスンを実際のプロジェクトで実行しないでください。
変更は、GitTree 内で行うか、ネイティブ Git コマンドを使用して行います。同じコピー内で両方を行うことはできません。結果の読み取りは常に安全です。メニュー ラベルは GitTree 2.0 独自の文字列から取得され、ネイティブ コマンドは使い捨てコピーの Git 2.43 で実行されました。 GitTree ステップは macOS、Windows、または Linux で実行されませんでした。
概念と状態の効果
通常、HEAD はブランチに名前を付け、コミットするとそのブランチが移動します。 HEAD がコミットに直接名前を付ける場合、それは detached です。新しいコミットは実際のものですが、名前を付けるものは何もないため、切り替えると reflog 経由でのみアクセス可能になります。そこに枝を置くとそれが修正されます。ブランチを作成しても、選択しない限りそのブランチには切り替わりません。
orphan ブランチは異なります。 HEAD は、まだコミットされていないブランチ (未誕生ブランチ) に名前を付けます。最初のコミットには親がないため、main と履歴を共有しません。 Git は、追跡されたファイルを作業フォルダーから削除します。追跡されず無視されたファイルはそのまま残ります。古い .gitignore が追跡されていた場合、そのルールが適用され、無視されたファイルは追跡されていないものとして表示されるようになります。古いブランチはすべてのコミットを保持します。
どちらの状態も正常であり、損傷はありません。ローカルの変更を上書きする可能性がある場合、チェックアウトは拒否されます。何も失われません。
正確なプロジェクトの状態を準備する
レッスン 18 の結果の 2 つの通常のコピーから開始し、オリジナルはそのままにしておきます。以下の本文は、ベースライン スタイルシート (BASE_CSS)、拡張スタイルシート (LAYOUT)、ダーティ エディット (DIRTY_LAYOUT)、孤立した Readme (ORPHAN_README)、ローカル メモ (LOCAL_NOTE)、および無視されたメモ (IGNORED_NOTE) です。
完全なファイル入力
各完全な UTF-8/LF 本文は、指定されたフェーズでのみ、最後の改行を付けて Markdown フェンスなしで保存します。 BASE_CSS は継承された 48rem 参照です。 LAYOUT は 52rem コミットです。 DIRTY_LAYOUT は、ステージングされていない別の 56rem リプレイです。 2 つのメモ ファイルは Survivor バリアントのみに属します。変更されていないメイン ファイルは、完全な L018/M 入力を継承します。
スタイル.css — BASE_CSS
:root {
color-scheme: light;
--page: #f7f8fa;
--surface: #ffffff;
--text: #17212e;
--link: #154ab5;
--line: #bac4d0;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--page);
color: var(--text);
font: 1rem/1.6 system-ui, sans-serif;
}
a {
color: var(--link);
}
.site-header,
main,
footer {
width: min(68rem, 100% - 2rem);
margin-inline: auto;
}
.site-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 1rem;
padding-block: 1rem;
}
.hero {
max-width: 48rem;
padding-block: 3rem;
}
h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
line-height: 1.2;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
gap: 1rem;
}
.feature-card {
padding: 1rem;
border: 1px solid var(--line);
border-radius: 0.75rem;
background: var(--surface);
}
section {
margin-block-end: 2rem;
}
button,
input {
font: inherit;
}
button,
input {
padding: 0.5rem 0.75rem;
}
:focus-visible {
outline: 3px solid var(--link);
outline-offset: 3px;
}
form {
display: grid;
max-width: 28rem;
gap: 0.5rem;
}style.css — レイアウト
:root {
color-scheme: light;
--page: #f7f8fa;
--surface: #ffffff;
--text: #17212e;
--link: #154ab5;
--line: #bac4d0;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--page);
color: var(--text);
font: 1rem/1.6 system-ui, sans-serif;
}
a {
color: var(--link);
}
.site-header,
main,
footer {
width: min(68rem, 100% - 2rem);
margin-inline: auto;
}
.site-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 1rem;
padding-block: 1rem;
}
.hero {
max-width: 52rem;
padding-block: 3rem;
}
h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
line-height: 1.2;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
gap: 1rem;
}
.feature-card {
padding: 1rem;
border: 1px solid var(--line);
border-radius: 0.75rem;
background: var(--surface);
}
section {
margin-block-end: 2rem;
}
button,
input {
font: inherit;
}
button,
input {
padding: 0.5rem 0.75rem;
}
:focus-visible {
outline: 3px solid var(--link);
outline-offset: 3px;
}
form {
display: grid;
max-width: 28rem;
gap: 0.5rem;
}スタイル.css — DIRTY_LAYOUT
:root {
color-scheme: light;
--page: #f7f8fa;
--surface: #ffffff;
--text: #17212e;
--link: #154ab5;
--line: #bac4d0;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--page);
color: var(--text);
font: 1rem/1.6 system-ui, sans-serif;
}
a {
color: var(--link);
}
.site-header,
main,
footer {
width: min(68rem, 100% - 2rem);
margin-inline: auto;
}
.site-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 1rem;
padding-block: 1rem;
}
.hero {
max-width: 56rem;
padding-block: 3rem;
}
h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
line-height: 1.2;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
gap: 1rem;
}
.feature-card {
padding: 1rem;
border: 1px solid var(--line);
border-radius: 0.75rem;
background: var(--surface);
}
section {
margin-block-end: 2rem;
}
button,
input {
font: inherit;
}
button,
input {
padding: 0.5rem 0.75rem;
}
:focus-visible {
outline: 3px solid var(--link);
outline-offset: 3px;
}
form {
display: grid;
max-width: 28rem;
gap: 0.5rem;
}README.md — ORPHAN_README
# GitTree Features documentation
This branch contains a documentation-only history for the fictional course project.
The landing page remains on main; no form submits information to a server.
Keep useful detached experiments under a branch name before switching away.ローカルレビュー.txt — LOCAL_NOTE
Local rehearsal note; preserve this file.reports/preview.txt — IGNORED_NOTE
Ignored rehearsal preview; preserve these bytes.GitTreeで
Command+Shift+P (Ubuntu では Ctrl+Shift+P) でパレットを開きます。
- 最初のコピーでは、グラフ内のコミット M を右クリックし、Check Out This Commit を選択します。ブランチピッカーには「Detached at …」と表示され、グラフには HEAD, detached が表示されます。
- LAYOUT を
styles.cssとして保存し、そのファイルをステージングして、概要style: widen the hero reading measureを使用してコミットします。パネルは、作業中に「切り離された HEAD」での変更をカウントします。 - 新しいコミットを右クリックし、Create Branch Here… を選択します。
experiment/layoutという名前を付け、チェックアウトのオプションをオフのままにして、Create Branch を選択します。通知には「実験/レイアウトを作成しました」と記載されています。そしてHEADはまだ切り離されたままです。 experiment/layoutラベルを右クリックして、Check Out Branch を選択します。 HEAD が再度アタッチされ、styles.cssは LAYOUT になり、mainは依然として M を指します。- Dirty checkout. 別のコピーで、
experiment/layoutでデタッチし、コミットせずにstyles.cssを DIRTY_LAYOUT に編集して、mainをチェックアウトしてみます。 「ローカル変更がメインの邪魔をしています」ダイアログにはファイルがリストされ、Commit First、Stash and Switch、および Discard and Switch が表示されます。 「キャンセル」を選択します。破棄するとコピーがrefs/ogt/trashに保持されますが、ここでは必要ありません。 - Orphan. 2 番目のコピーでは、クリーンなワークツリーを使用して、パレットから Create Orphan Branch… を実行します。 「…に孤立したブランチを作成しますか?」 「
orphan-docs」と入力します。ダイアログには、作業フォルダーから離れる追跡ファイルの数、追跡されない無視されたファイルが残ること、古いコミットがrefs/ogt/trashの下に保持されることが示されます。キャンセルにフォーカスがあります。 Create Orphan Branchを選択します。 - 通知には「新しい孤立ブランチ orphan-docs に切り替えました。元に戻すと元に戻ります。」と書かれています。フォルダーには追跡されたファイルがなく、グラフには新しいブランチにコミットがないことが示されています。 ORPHAN_README から
README.mdを作成し、ステージングして、概要docs: start the separate project guideを使用してコミットします。新しいコミットには親がありません。 - 比較:
mainにはまだすべてのコミットがあります。孤立したブランチは別のルートです。どちらのコピーもプッシュしないでください。
コース内のすべての通常のコミット: Summary は指定された件名、Description は空、オプション Amend Previous Commit、Skip Hooks、Add Signed-off-by、Different Author、Push After Commit、および Allow Empty Commit はオフのままです。
ターミナル内
最初のコピーでは次のようになります。
BASE_SHA="$(git rev-parse main)"
git switch --detach "$BASE_SHA"
git symbolic-ref --quiet --short HEAD; echo $?最後のコマンドは 1 を出力します: HEAD はブランチではありません。 LAYOUT を styles.css として保存し、次のようにします。
git commit --quiet -am "style: widen the hero reading measure"
git branch experiment/layout
git symbolic-ref --quiet --short HEAD; echo $?
git rev-parse HEAD^ main
git switch --quiet experiment/layout
git symbolic-ref --short HEAD
git status --short1
experiment/layout作成コマンドは HEAD を付加しません (2 番目のクエリでも 1 が出力されます)、rev-parse の 2 つの ID は等しく (M)、ステータスは空です。 experiment/layout でデタッチされた別のコピーで、styles.css を編集して git switch main を実行します。Git は「次のファイルに対するローカルの変更はチェックアウトによって上書きされます」というメッセージで拒否され、ファイルは変更されません。
2 番目のコピーでは、クリーンなツリーが使用されています。
git switch --orphan orphan-docs
git symbolic-ref --short HEAD
git rev-parse --verify --quiet HEAD; echo $?
git ls-filesorphan-docs
1ブランチは存在しますが、コミットがなく (rev-parse は 1 を終了します)、ls-files は何も出力しません。追跡されたファイルはフォルダーから削除されますが、local-review.txt と reports/ はそのまま残り、未追跡として表示されます。 README.md を作成し、次のようにします。
git add -- README.md
git commit --quiet -m "docs: start the separate project guide"
git ls-tree -r --name-only HEAD
git rev-list --max-parents=0 --count HEAD
git merge-base --all main orphan-docs; echo $?README.md
1
1新しいブランチには 1 つのルート コミットがあり、main との共通の祖先はありません (merge-base は何も出力せずに 1 を終了します)。
結果
Where you end: 切り離されたコミットは experiment/layout という名前でチェックアウトされていますが、main はまだ M を指しており、ツリーはクリーンです。孤立したコピーには、親のない 1 つのルート コミットを持つ orphan-docs があり、古い追跡ファイルはフォルダーから削除されていますが、main によって保持されており、何もプッシュされませんでした。
よくある間違い
- 分離された HEAD にコミットし、ブランチを使用せずに切り替えると、reflog を介してのみコミットに到達できるようになります。
Create Branch Here…が新しいブランチに切り替わることを期待しています。- コミットされていない追跡された変更を含む孤立したブランチを開始するか、それによって
mainが削除されると考えられます。 - 無視されたファイルは、その
.gitignoreがフォルダから出た後も無視されたままであると仮定します。
何か問題が発生した場合
切り離されたコミットに名前を付けずに残した場合は、reflog (レッスン 29) を開いてそこにブランチを置きます。孤立したブランチが間違いだった場合、新しいブランチにコミットがない間、Undo は元に戻ります。それ以外の場合は、main をもう一度チェックしてください。チェックアウトを拒否しても何も変わりません。
理解度を確認してください
各質問に答えてから、その理由を読みましょう。 「必須」とマークされた質問は、レッスンの完了にカウントされます。
6 個中 0 個が正解です
必須の質問に正しく答えると、レッスンを完了できます。
このブラウザで確認しました。
練習する
各状態 (ブランチ、デタッチ、未誕生) で HEAD が指す場所、デタッチされたコミットとそのブランチの ID、孤立ブランチに git ls-files が出力したものをレポートします。次に、.gitignore がなくなったときに無視されたファイルに何が起こるかを予測します。
あなた自身の確認: サイトはあなたのコンピュータを認識できません。
レッスンを完了するには、必須の質問に正しく答え、実践的な演習を確認してください。
要約
- 切り離されたコミットには、到達可能な状態を保つためにブランチが必要です。
- 孤立したブランチは別のルートを開始し、追跡されたファイルをフォルダーから削除します。
- チェックアウトが拒否されると、編集内容が保護されます。
関連している
用語集の用語の紹介
切り離された HEAD — HEAD منفصل;孤児ブランチ — فرع يتيم;胎児の枝 — فرع غير مولود;ルートコミット — إيداع جذري。
ビデオトランスクリプト
ビデオのナレーションが次々と流れます。
トランスクリプトを表示する
- ヘッドはどこですか? 3 つの州。
- HEAD はブランチ、コミット、または まだコミットのないブランチ。
- デタッチ中に行われたコミットは本物ですが、 名前は何もありません。
- そのコミットのブランチがそれを保持します 到達可能。
- コミット M を右クリックし、「チェック」を選択します。 このコミットを終了します。
- スタイルシートを変更し、ステージングして、 一度コミットしてください。
- 新しいコミットを右クリックし、 チェックアウトせずにここで分岐します。
- 今すぐブランチをチェックしてください。ヘッドが付属します またまた。
- 編集を保存していない場合、チェックアウトは 拒否した。キャンセルするとすべてが保持されます。
- 最初にコミットするか、スタッシュしてから切り替えるか、 捨てる。避けるべきは破棄です。
- 新しい履歴を作成するには、Create Orphan を実行します。 パレットから分岐します。
- 追跡されたファイルの流出数をカウントします。 追跡されず無視されたものはそのまま残ります。
- 確認する。フォルダーには追跡されたファイルがありません。
- Readme を追加してコミットします。このコミットには、 親はいない。
- ターミナルでは、symbolic-ref は次の場合に 1 を終了します。 ヘッドが外れています。
- 未誕生のブランチで、HEAD の rev-parse 失敗します。
- コミット後、merge-base は何も検出しません 共通の祖先。
- ブランチせずに終了した場合、reflog まだあります。
- 練習: 各状態に HEAD という名前を付けてから、 無視されるファイルを予測します。
- 次にプッシュ後のミスをリカバリーします。