콘텐츠로 건너뛰기
GitTree

레슨 31 · 회복

분리된 작업을 유지하고 고아 기록을 시작합니다.

분리된 HEAD에서 커밋을 떠나기 전에 이름을 지정하고 별도의 복사본으로 고아 브랜치를 시작하여 제거되는 것과 유지되는 것을 확인하세요.

이 브라우저에 진행 상황이 저장되었습니다.

재생하면 YouTube에서 동영상이 로드됩니다(개인정보 보호 강화 모드).

영어 내레이션 · English and Arabic 캡션

비디오 페이지 열기YouTube에서 시청하기

무엇을 배울 것인가

  • 부착된 HEAD, 분리된 HEAD, 아직 태어나지 않은 HEAD를 구분합니다.
  • 연결 가능한 상태로 유지되도록 분리된 커밋에 브랜치를 배치합니다.
  • 추적된 파일, 추적되지 않은 파일 및 이전 분기에 대해 고아 분기가 수행하는 작업을 예측합니다.
  • 로컬 변경으로 인한 결제 거부를 읽어보세요.

시작하기 전에

18과 결과 M의 일회용 복사본 2개. 첫 번째에서는 분기 대신 커밋 M 자체를 확인하고 거기에서 작은 스타일시트를 변경한 후 유지하려고 합니다. 두 번째에서는 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과 결과의 두 개의 별도 일반 복사본에서 시작하고 원본을 그대로 둡니다. 아래 본문은 기본 스타일시트(BASE_CSS), 확대된 스타일시트(LAYOUT), 더티 편집(DIRTY_LAYOUT), 고아의 추가 정보(ORPHAN_README), 로컬 메모(LOCAL_NOTE) 및 무시된 메모(IGNORED_NOTE)입니다.

완전한 파일 입력

각 전체 UTF-8/LF 본문은 명시된 단계에서만 최종 개행 문자와 Markdown 울타리 없이 저장됩니다. BASE_CSS는 상속된 48rem 참조입니다. LAYOUT은 52rem 커밋입니다. DIRTY_LAYOUT은 별도의 스테이지되지 않은 56rem 재생입니다. 두 개의 메모 파일은 생존자 변형에만 속합니다. 변경되지 않은 기본 파일은 전체 L018/M 입력을 상속합니다.

styles.css — BASE_CSS

파일 발췌 · 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;
}

styles.css — 레이아웃

파일 발췌 · 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;
}

styles.css — DIRTY_LAYOUT

파일 발췌 · 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: 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.

local-review.txt — LOCAL_NOTE

출력
Local rehearsal note; preserve this file.

보고서/preview.txt — IGNORED_NOTE

출력
Ignored rehearsal preview; preserve these bytes.

GitTree에서

Command+Shift+P(Ubuntu에서는 Ctrl+Shift+P)를 사용하여 팔레트를 엽니다.

  1. 첫 번째 복사본에서는 그래프의 커밋 M을 마우스 오른쪽 버튼으로 클릭하고 Check Out This Commit을 선택합니다. 분기 선택기에 "...에서 분리됨"이 표시되고 그래프에 HEAD, detached이 표시됩니다.
  2. LAYOUT을 styles.css로 저장하고 해당 파일을 스테이징한 다음 요약 style: widen the hero reading measure으로 커밋합니다. 패널은 작업하는 동안 "분리된 HEAD의" 변경 사항을 계산합니다.
  3. 새 커밋을 마우스 오른쪽 버튼으로 클릭하고 Create Branch Here…을 선택합니다. 이름을 experiment/layout로 지정하고 확인 옵션을 끈 다음 Create Branch을 선택하세요. '실험/레이아웃이 생성되었습니다'라는 알림이 표시됩니다. HEAD는 여전히 분리되어 있습니다.
  4. experiment/layout 라벨을 마우스 오른쪽 버튼으로 클릭하고 Check Out Branch을 선택합니다. HEAD가 다시 연결되고 styles.css은 LAYOUT이고 main는 여전히 M을 가리킵니다.
  5. Dirty checkout. 다른 복사본에서 experiment/layout에서 분리하고 커밋하지 않고 styles.css을 DIRTY_LAYOUT으로 편집한 다음 main을 체크아웃해 보세요. "로컬 변경 사항이 메인을 방해하고 있습니다" 대화 상자에는 파일이 나열되고 Commit First, Stash and Switch 및 Discard and Switch이 제공됩니다. 취소를 선택하십시오. 폐기하면 refs/ogt/trash 아래에 복사본이 유지되지만 여기서는 필요하지 않습니다.
  6. Orphan. 깨끗한 작업 트리를 사용하여 두 번째 복사본에서는 팔레트에서 Create Orphan Branch…을 실행합니다. "...에 고아 분기를 생성하시겠습니까?" orphan-docs을(를) 입력하세요. 대화상자에는 작업 폴더를 떠나는 추적된 파일의 수, 추적되지 않은 파일과 무시된 파일이 남아 있는 파일, 이전 커밋이 refs/ogt/trash에 보관되어 있는 파일이 나와 있습니다. 취소에 포커스가 있습니다. Create Orphan Branch를 선택하세요.
  7. 알림에는 "새로운 고아 지점 orphan-docs로 전환되었습니다. 실행 취소는 다시 전환됩니다."라고 표시됩니다. 폴더에는 추적된 파일이 없으며 그래프에는 새 분기에 대한 커밋이 표시되지 않습니다. ORPHAN_README에서 README.md을(를) 생성하고 스테이징한 다음 요약 docs: start the separate project guide을(를) 사용하여 커밋합니다. 새 커밋에는 상위가 없습니다.
  8. 비교: main에는 여전히 모든 커밋이 있습니다. 고아 지점은 별도의 루트입니다. 두 사본 중 하나를 푸시하지 마십시오.

과정의 모든 일반적인 커밋에 대해: Summary는 명시된 주제이고, Description는 비어 있으며, 옵션 Amend Previous Commit, Skip Hooks, Add Signed-off-by, Different Author, Push After Commit 및 Allow Empty Commit는 꺼져 있습니다.

터미널에서

첫 번째 사본에서:

Command · bash
BASE_SHA="$(git rev-parse main)"
git switch --detach "$BASE_SHA"
git symbolic-ref --quiet --short HEAD; echo $?

마지막 명령은 1을(를) 인쇄합니다. HEAD는 분기가 아닙니다. 레이아웃을 styles.css로 저장한 후:

Command · bash
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 --short
출력
1
experiment/layout

생성 명령은 HEAD를 연결하지 않으며(두 번째 쿼리는 여전히 1을 인쇄함) rev-parse의 두 ID가 동일하고(M) 상태가 비어 있습니다. experiment/layout에서 분리된 다른 복사본에서 styles.css을 편집하고 git switch main를 실행합니다. Git은 "다음 파일에 대한 로컬 변경 사항이 체크아웃 시 덮어쓰여집니다"라는 메시지를 거부하고 파일은 그대로 유지됩니다.

깨끗한 트리가 있는 두 번째 복사본에서는 다음과 같습니다.

Command · bash
git switch --orphan orphan-docs
git symbolic-ref --short HEAD
git rev-parse --verify --quiet HEAD; echo $?
git ls-files
출력
orphan-docs
1

분기가 존재하지만 커밋이 없으며(rev-parse 종료 1) ls-files는 아무것도 인쇄하지 않습니다. 추적된 파일은 폴더에서 사라지지만 local-review.txt 및 reports/은 그대로 유지되어 이제 추적되지 않은 것으로 표시됩니다. README.md을(를) 생성한 후 다음을 수행합니다.

Command · bash
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

새 브랜치에는 하나의 루트 커밋이 있고 main와 공통 조상이 없습니다(merge-base는 아무것도 인쇄하지 않고 1을 종료합니다).

결과

Where you end: 분리된 커밋의 이름은 experiment/layout이고 체크아웃되었습니다. main은(는) 여전히 M을 가리키며 트리는 깨끗합니다. 고아 복사본에는 상위가 없는 하나의 루트 커밋이 있는 orphan-docs이 있고, 이전 추적 파일은 폴더에서 사라졌지만 main에 보관되었으며 아무것도 푸시되지 않았습니다.

일반적인 실수

  • 분리된 HEAD에서 커밋하고 분기 없이 전환하여 reflog를 통해서만 커밋에 도달할 수 있게 됩니다.
  • Create Branch Here…이(가) 새 분기로 전환될 것으로 예상됩니다.
  • 커밋되지 않은 추적된 변경 사항으로 고아 브랜치를 시작하거나 main을(를) 삭제한다고 생각합니다.
  • 무시된 파일이 해당 .gitignore이(가) 폴더를 떠난 후에도 무시된 상태로 유지된다고 가정합니다.

뭔가 잘못되면

이름 없이 분리된 커밋을 남겨둔 경우 reflog(29강)를 열고 그 위에 브랜치를 추가하세요. 고아 브랜치가 실수인 경우 Undo는 새 브랜치에 커밋이 없는 동안 다시 전환합니다. 그렇지 않으면 main을(를) 다시 확인하세요. 거부된 결제는 아무것도 바꾸지 않았습니다.

이해도를 확인해보세요

각 질문에 답한 후 그 이유를 읽어보세요. '필수'라고 표시된 질문은 수업 완료에 반영됩니다.

  1. 질문 1/6

    분리된 HEAD란 무엇입니까?

    답을 하나 선택하세요.

  2. 질문 2/6

    다음 중 고아 지점에 대한 설명으로 옳은 것은 무엇입니까? (객관식)

    해당하는 답을 모두 선택하세요.

  3. 질문 3/6
    필수

    분리된 HEAD에 커밋하고 체크아웃하지 않고 거기에 experiment/layout을 생성한 다음 HEAD를 살펴봅니다. 그것은 무엇입니까?

    답을 하나 선택하세요.

  4. 질문 4/6

    입력 변경: main을(를) 체크아웃하려고 할 때 작업 트리에 styles.css에 대한 커밋되지 않은 편집 내용이 있습니다. 무슨 일이 일어나나요?

    답을 하나 선택하세요.

  5. 질문 5/6
    필수

    git ls-files는 git switch --orphan orphan-docs 바로 뒤에 아무것도 인쇄하지 않습니다. 뭔가 문제가 있나요?

    답을 하나 선택하세요.

  6. 질문 6/6
    필수

    orphan-docs에 대한 첫 번째 커밋 이후 어떤 리드백에서 그것이 별도의 루트임을 보여줍니까? (객관식)

    해당하는 답을 모두 선택하세요.

6개 중 0개 정답

수업을 완료하려면 필수 질문에 올바르게 답하세요.

이 브라우저에서 확인했습니다.

연습

각 상태(branch, detached, unborn)에서 HEAD가 가리키는 위치, 분리된 커밋의 ID와 해당 브랜치, 고아 브랜치에 인쇄된 git ls-files 내용을 보고합니다. 그런 다음 .gitignore가 사라지면 무시된 파일에 어떤 일이 발생할지 예측하세요.

귀하의 확인: 사이트에서 귀하의 컴퓨터를 볼 수 없습니다.

수업을 완료하려면 필수 질문에 올바르게 답하고 실제 연습을 확인하세요.

요약

  • 분리된 커밋에는 연결 가능한 상태를 유지하기 위한 분기가 필요합니다.
  • 고아 분기는 별도의 루트를 시작하고 폴더에서 추적된 파일을 제거합니다.
  • 거부된 체크아웃은 편집 내용을 보호합니다.

용어집 소개

분리된 HEAD — HEAD منصل; 고아 지점 — froع يتيم; 아직 태어나지 않은 가지 — phرع ghira molud; 루트 커밋 — إيداع ججري.

비디오 대본

영상의 나레이션, 큐별로.

성적표 표시
  1. HEAD는 어디에 있나요? 세 가지 상태.
  2. HEAD는 브랜치, 커밋 또는 아직 커밋이 없는 브랜치.
  3. 분리된 동안 이루어진 커밋은 실제이지만 아무것도 이름을 지정하지 않습니다.
  4. 해당 커밋의 브랜치가 이를 유지합니다. 도달 가능.
  5. 커밋 M을 마우스 오른쪽 버튼으로 클릭하고 확인을 선택합니다. 이 커밋을 종료합니다.
  6. 스타일시트를 변경하고, 준비하고, 한 번 커밋하십시오.
  7. 새 커밋을 마우스 오른쪽 버튼으로 클릭하고 확인하지 않고 여기로 분기하세요.
  8. 이제 지점을 확인해 보세요. HEAD가 부착되었습니다. 다시.
  9. 저장되지 않은 편집 내용이 있으면 체크아웃됩니다. 거절했습니다. 취소하면 모든 것이 유지됩니다.
  10. 먼저 커밋하고 숨긴 후 전환하거나 폐기합니다. 버리는 것은 피하는 것입니다.
  11. 새로운 기록을 보려면 Create Orphan을 실행하세요. 팔레트에서 분기합니다.
  12. 떠나는 추적된 파일의 수를 계산합니다. 추적되지 않고 무시된 사람은 그대로 유지됩니다.
  13. 확인하다. 폴더에 추적된 파일이 없습니다.
  14. Readme를 추가하고 커밋합니다. 이 커밋에는 부모가 없습니다.
  15. 터미널에서 다음 경우에 Symbolic-ref는 1로 종료됩니다. HEAD가 분리되었습니다.
  16. 아직 태어나지 않은 브랜치에서 HEAD의 개정 구문 분석 실패합니다.
  17. 커밋 후 merge-base는 다음을 찾지 않습니다. 공통 조상.
  18. 브랜치 없이 떠난 경우, 리플로그 아직도 가지고 있습니다.
  19. 연습: 각 주에 HEAD라는 이름을 지정한 다음 무시된 파일을 예측합니다.
  20. 다음으로 푸시 후 실수를 복구하십시오.