실습 저장소에 변경 기록 남기기
75분 안팎
학습 목표
작업 트리·스테이지·변경 기록을 구분합니다.
개념
변경 이유를 읽을 수 있는 묶음으로 남깁니다
독서 프로그램에서 쪽수 0을 허용하도록 고쳤는데 동료는 예전 안내를 보고 입력을 거절할 수 있습니다. 코드와 문서를 함께 비교하고 변경 이유를 남기면 이런 어긋남을 찾기 쉽습니다. Git의 기록은 저장 버튼과 다릅니다. 저장한 파일 중 어떤 상태를 한 묶음으로 남길지 작성자가 선택합니다. 이 레슨에서는 작은 쪽수 검증 함수를 바꾸며 작업 트리, 스테이지, 커밋을 구분합니다.
이번 모듈의 로컬 실습에는 Python 3.9 이상, Git, Bash를 사용합니다. Python 표준 라이브러리 외 패키지는 설치하지 않습니다. 실습 ZIP은 devinkr 저장소와 그 하위 폴더 밖에 풀어 사용합니다. 터미널에서 pwd로 현재 위치를 확인하고 git rev-parse --show-toplevel로 상위 저장소가 있는지 확인합니다. 상위 저장소 경로가 나오면 실습을 시작하지 않고 독립된 폴더로 이동합니다. 새 폴더에서 not a git repository 오류가 나는 것은 초기화 전의 정상 상태입니다.
세 위치의 차이를 먼저 확인합니다
작업 트리는 편집기로 읽고 수정하는 현재 파일입니다. 스테이지는 다음 커밋에 넣을 파일 내용을 선택해 둔 영역입니다. 커밋은 선택한 내용을 변경 설명과 함께 저장소에 남긴 기록입니다. 파일을 저장해도 스테이지는 자동 갱신되지 않습니다. git add reading.py 뒤에 다시 파일을 수정하면 스테이지에는 이전 내용, 작업 트리에는 이후 내용이 놓입니다. 커밋 직전에 다시 확인해야 하는 이유입니다.
git diff는 기본적으로 작업 트리와 스테이지의 차이를 보여 줍니다. git diff --cached는 스테이지와 현재 커밋의 차이를 보여 줍니다. 새 파일은 추적 전이므로 기본 diff에 내용이 나타나지 않을 수 있습니다. git status --short에서 ??를 찾고 파일을 직접 읽습니다. add 후 cached 비교에서 의도한 새 파일을 확인합니다. diff가 비었다는 관찰만으로 파일 전체가 기록되었다고 판단하지 않습니다.
짧은 상태 표시에는 두 칸이 있습니다. 첫 칸은 스테이지의 변경, 둘째 칸은 작업 트리의 변경을 나타냅니다. 앞쪽 M은 스테이지에 수정이 있고 뒤쪽 M은 스테이지 이후에 수정이 있다는 뜻입니다. MM은 두 위치가 모두 달라졌다는 신호입니다. 표시가 헷갈리면 긴 git status를 함께 읽고 두 diff를 따로 실행합니다. 깨끗한 상태도 테스트 통과나 요구 충족을 의미하지는 않습니다.
한 목적의 코드와 문서를 함께 선택합니다
제공된 reading.py는 쪽수가 0보다 커야 참을 반환합니다. 업무 요구를 0 이상으로 바꾸면 조건의 비교 기호를 수정해야 합니다. README에도 0이 허용된다고 적어야 동료의 입력 안내가 맞습니다. 두 파일은 같은 목적이므로 같은 커밋에 담습니다. 화면 색상이나 다른 집계 기능처럼 목적이 다른 변경은 섞지 않습니다. 커밋 메시지는 무엇을 바꿨는지와 왜 필요한지를 다음 사람이 이해할 수 있게 씁니다.
학습자가 직접 실행할 순서는 git init, 실습 저장소의 작성자 설정, 시작 파일의 명시적 add, 시작 커밋, 코드·문서 수정, 두 diff 확인, 수정 파일 add, 변경 커밋입니다. git config user.name과 user.email은 이 실습 폴더에서만 설정합니다. --global은 사용하지 않습니다. 가상 주소 learner@example.invalid는 로그인 자격증명이 아니라 기록 작성자 표시입니다. 원격 저장소나 push는 이 실습에 필요하지 않습니다.
git add .는 편리하지만 생성 파일이나 개인 설정까지 선택할 수 있습니다. 이번에는 git add reading.py README.md처럼 파일 이름을 명시합니다. 스테이지에서 파일을 빼고 싶으면 이미 시작 커밋이 있는 상태에서 git restore --staged README.md를 사용할 수 있습니다. 이는 편집 내용 자체를 지우는 명령과 다릅니다. 내용을 덮어쓰는 restore와 혼동하지 않도록 먼저 status와 cached diff를 확인합니다.
전달할 파일과 생성 파일을 나눕니다
.gitignore에는 __pycache__/, *.pyc, records.json, *.tmp, .env 같은 생성물·개인 설정 패턴을 둡니다. 가상 CSV, 코드, 테스트, README는 추적합니다. ignore는 이미 추적한 파일을 자동으로 빼지 않습니다. git ls-files로 추적 목록을 확인하는 이유입니다. 개인 자료를 실수로 기록한 경우 다음 커밋에서 삭제해도 과거 기록에 남을 수 있으므로 공개하지 않고 담당자에게 상황을 알립니다.
이번 작은 실습의 .gitignore는 자동 검사에 쓰는 record.sh와 verify_git.py도 제외합니다. 이 선택은 실습 저장소의 세 파일만 비교하려는 목적입니다. 실제 프로젝트에서는 검증 스크립트도 함께 추적해야 합니다. 작은 실습의 추적 정책을 미션에 그대로 옮기지 않습니다. 미션은 기존 Python·SQL·HTTP 기능과 모든 검사 파일을 전달 대상으로 삼습니다.
기록과 검사 근거를 구분합니다
git log --oneline은 기록의 짧은 목록을 보여 줍니다. git show --stat HEAD로 최근 기록에 어떤 파일이 포함되었는지 살펴보고 git show HEAD로 줄 차이를 읽습니다. 해시나 날짜는 실행마다 달라질 수 있으므로 고정 출력으로 외우지 않습니다. 최근 메시지와 변경 파일이 요구에 맞는지가 판단 기준입니다. 커밋이 두 개라는 사실보다 각 기록을 설명할 수 있는지가 더 중요합니다.
starter의 record.sh는 코드만 스테이지하고 수정한 README를 빠뜨립니다. 검사기는 독립 임시 폴더에서 이 스크립트를 실행한 뒤 기록 수, 최근 메시지, 추적 목록, 남은 변경, 최근 기록의 문서 포함을 확인합니다. solution은 빠진 파일 선택을 고친 예입니다. 검사기는 자신의 실제 프로젝트 기록을 대신 평가하지 않습니다. 본인이 남긴 기록의 diff와 실행 근거는 동료가 별도로 리뷰합니다.
이 작성 세션에서는 Git 커밋 실행이 금지되어 자동 검사를 실행하지 않았습니다. 따라서 Git 실습은 외부 검증 대기로 표시합니다. 아래 명령은 다운로드한 독립 실습에서 학습자가 수행할 절차이며 출력은 제공하지 않습니다. 학습자의 환경에서 결과를 직접 확인하고 docs에 명령·결과·해석을 적습니다. 서재의 협업 장은 리뷰 질문을 더 연습할 때 읽습니다.
Author identity unknown은 작성자 표시 설정을 확인하라는 뜻이고 nothing to commit은 선택된 변경이 없다는 뜻입니다. 파일을 저장했는지, add했는지, 기존 기록과 차이가 있는지 순서대로 확인합니다. not a git repository는 위치 또는 초기화 상태를 먼저 살핍니다. 오류를 없애려고 상위 프로젝트에서 명령을 반복하지 않습니다. 이번 실습이 끝나면 어느 상태가 기록되는지와 코드·문서를 함께 선택한 이유를 설명합니다.
따라하기
저장소 경계 확인
다운로드 폴더에서만 확인합니다. 상위 저장소 경로가 나오면 독립 위치로 이동합니다. 초기화 전 not a git repository는 예상한 상태입니다. 이 단계는 작성 세션에서 실행하지 않았습니다.
pwd
git rev-parse --show-toplevel코드와 문서의 변경 선택
빈 독립 폴더에 starter 파일을 놓고 시작 기록을 남깁니다. 이후 reading.py의 비교를 0 이상으로, README의 안내를 0 허용으로 수정합니다. 작성자 설정은 현재 실습 폴더에만 적용합니다.
git init
git config user.name "Reading Learner"
git config user.email "learner@example.invalid"
git add .gitignore reading.py README.md
git commit -m "독립 독서 실습의 시작 상태"
python3 -c 'from pathlib import Path; p = Path("reading.py"); p.write_text(p.read_text().replace("pages > 0", "pages >= 0")); r = Path("README.md"); r.write_text(r.read_text() + "\n0쪽도 유효합니다.\n")'
git diff -- reading.py README.md
git add reading.py README.md
git diff --cached
git commit -m "쪽수 0도 정상 기록으로 처리"기록과 추적 목록 검토
기록 메시지·두 파일의 변경·남은 수정 여부를 비교합니다. 자동 검사는 독립 임시 폴더에서 커밋을 만들므로 외부 환경에서만 실행합니다. starter의 record.sh에서 빠진 문서 스테이지를 고칩니다.
git log --oneline
git show --stat HEAD
git ls-files
git status --short
bash check.sh확인 문제
실습
record.sh의 두 번째 스테이지에서 빠진 README.md를 포함합니다. tests 역할의 verify_git.py는 수정하지 않습니다. bash check.sh는 저장소 밖 임시 폴더에서 시작·변경 커밋 두 개를 만들고 최신 메시지·코드·문서 포함·추적 파일·깨끗한 상태를 검사합니다. 실습 원본 안에서 실행하면 상위 저장소를 건드리지 않고 임시 폴더만 사용합니다. 자신의 실제 변경 기록 리뷰는 별도입니다.
실행 명령
bash check.sh
기대 결과
외부에서 GIT|2 commits|tracked files|clean|PASS. 현재는 커밋 실행 금지로 PENDING입니다.
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- 다른 사람이 프로그램을 실행하도록 준비한 내용을 설명합니다.