Devin.KR

Git과 재현 가능한 README

90분 안팎

학습 목표

변경 차이와 실행 전제 조건을 남깁니다.

개념

왜 동작과 변경 기록을 함께 남길까요

혼자 실행되는 스크립트라도 다음 작업자가 어떤 변경 때문에 동작이 달라졌는지 이해해야 합니다. Git은 파일 변경을 비교하고 단계별로 검토할 수 있게 하며 README는 실행 전제와 절차를 설명합니다. 안내판 프로젝트의 다음 모듈은 여기서 만든 폴더와 명령 계약을 이어받습니다. 따라서 설정 예시와 실제 개인 설정을 구분하고 새 폴더에서도 같은 절차를 재현하도록 안내합니다. 이번 연습은 개인 복사본에 Git 저장소를 초기화하고 인덱스에 변경을 올려 검토하는 데까지 수행합니다.

작업 트리와 인덱스를 구분합니다

작업 트리는 편집하는 실제 파일입니다. 인덱스는 다음 변경 기록에 포함할 내용을 미리 모아 둔 영역입니다. git add는 파일의 현재 내용을 인덱스에 넣습니다. add 이후 다시 파일을 고치면 인덱스와 작업 트리의 내용은 달라질 수 있습니다. git diff는 보통 작업 트리와 인덱스의 차이를, git diff --cached는 인덱스와 현재 기록의 차이를 보여 줍니다. 초기 저장소에서는 cached 비교로 처음 포함할 파일을 검토할 수 있습니다. 아직 커밋이 없으므로 git diff HEAD처럼 존재하지 않는 기준을 사용하지 않습니다.

상태 표시를 다음 행동으로 연결합니다

git status --short의 앞 두 칸은 인덱스 상태와 작업 트리 상태입니다. A로 시작하는 파일은 새로 인덱스에 추가된 파일이며 ??는 아직 추적되지 않은 파일입니다. 파일이 목록에 안 보인다고 모두 무시된 것으로 단정하지 말고 git check-ignore로 규칙을 확인합니다. git ls-files는 인덱스에 있는 경로를 확인하는 데 사용합니다. 이 실습은 신규 개인 저장소에서 진행하므로 이미 추적되던 비밀 파일을 제거하거나 과거 기록을 다시 쓰는 상황과 구분합니다. 저장소 밖의 기존 프로젝트에는 초기화 연습을 하지 않습니다.

예시 설정과 실제 설정을 분리합니다

workspace/app.example.env에는 공개 가능한 APP_NAME 예시만 둡니다. 실제 실행은 이를 복사한 workspace/app.env를 읽습니다. .gitignore에는 실제 설정, *.secret, 생성 로그·데이터·후속 표시 파일을 적습니다. ignore 규칙은 새 파일이 자동 포함되는 것을 막는 장치이며 이미 추적 중인 파일을 숨기거나 접근 권한을 줄이는 장치가 아닙니다. 비밀을 인덱스에 올려 놓은 뒤 ignore만 추가해 해결했다고 판단하지 않습니다. 실습 검사기는 가짜 token.secret을 만들고 실제 설정과 함께 인덱스에서 제외되는지 확인합니다.

검토할 범위를 직접 선택합니다

git add . 대신 .gitignore, README.md, scripts, workspace/app.example.env를 명시적으로 추가합니다. 전체 추가가 언제나 잘못된 것은 아니지만 규칙을 작성하는 연습에서는 대상을 선택하는 편이 변경 범위를 이해하기 쉽습니다. git diff --cached --name-only로 경로를 확인한 뒤 git diff --cached로 내용을 읽습니다. 검사기는 git init과 git add만 임시 복사본에서 사용합니다. 커밋이나 push는 수행하지 않으며 별도 계정 설정이나 원격 저장소 연결도 필요하지 않습니다. 현재 저장소에 새 기록을 남기는 작업과 혼동하지 않습니다.

README를 실행 가능한 인계로 만듭니다

환경 전제에는 Linux·Bash·Git·Python과 일반 사용자 조건을 적습니다. 실행 안내는 zip을 푼 루트에서 설정 예시를 복사하고 준비 스크립트와 검사를 실행하는 순서로 작성합니다. 성공 시 만들어지는 폴더와 실패 시 만들어지면 안 되는 표시 파일도 설명합니다. 실패 재현은 원본 작업 폴더가 아닌 별도 복사본에서 설정을 없애거나 잘못된 이름으로 바꾸어 수행합니다. 개인 절대 경로를 모든 사용자에게 그대로 입력하라고 안내하지 않고 프로젝트 루트의 의미와 다른 위치의 호출 방법을 함께 적습니다.

재현성과 추적의 한계를 적습니다

스크립트가 하는 일과 하지 않는 일을 명확히 씁니다. 이 단계는 서비스를 기동하거나 실제 배포를 하는 단계가 아니라 폴더와 설정을 준비하는 단계입니다. 테스트 통과는 제공 fixture에서의 증거이지 모든 운영 환경에 대한 보장이 아닙니다. README에는 수정 이유와 검토한 차이, check.sh 결과를 연결합니다. 실행 날짜나 사용자 이름처럼 달라지는 값은 따라하기의 고정 출력으로 약속하지 않습니다. 텍스트 차이의 문맥을 읽는 방법은 diff 더 읽기로 이어지고 이후 모듈에서는 이 기록 위에 빌드·릴리스 명세를 추가합니다.

추적 대상과 무시 규칙을 함께 점검합니다

git check-ignore는 경로가 어떤 무시 규칙에 해당하는지 확인하는 명령입니다. 자세한 규칙 위치가 필요하면 -v 옵션을 사용할 수 있습니다. git ls-files는 인덱스의 경로를 보여 주므로 실제 설정이 추적 대상에 들어갔는지를 별도로 확인합니다. 무시 규칙에 맞는다는 설명과 인덱스에서 제외되었다는 증거를 혼동하지 않습니다. 이번 새 저장소에서는 app.example.env만 인덱스에 있고 app.env는 무시되는 상태가 목표입니다. 두 명령의 출력에 같은 workspace 접두사가 나타나도 파일명이 다르므로 예시 설정과 개인 설정을 끝까지 구분해 읽습니다.

내용 차이와 실행 모드를 함께 검토합니다

스크립트는 내용뿐 아니라 실행 가능 여부도 검토할 대상입니다. Git은 일반적으로 일반 파일의 실행 비트 차이를 기록하지만 소유자나 전체 권한 모드를 저장하는 도구는 아닙니다. 따라서 저장소에서 파일을 받았다는 사실만으로 app.env가 600이라고 판단하지 않고 준비 절차에서 권한을 설정합니다. git diff --cached --summary는 추가된 파일과 모드 변경 같은 요약을 확인할 때 유용합니다. README에서 bash로 호출하는 스크립트와 직접 호출하는 스크립트를 구분하면 실행 비트가 필요한 대상을 설명할 수 있습니다. 최종 검토에서는 의도한 스크립트와 공개 예시만 포함되어 있는지 내용을 읽습니다.

실습에서 적용할 구현

위 설명을 아래 구현과 연결해 읽습니다. 시작 코드의 scripts/record.sh를 수정한 뒤 검사합니다. ROOT는 scripts의 부모인 프로젝트 루트이며 이 코드는 해당 폴더 계약을 전제로 합니다.

#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd -P)"
cd "$ROOT"
git init -q
git add .gitignore README.md scripts workspace/app.example.env
printf 'change recorded in index\n'

따라하기

인덱스에 검토 대상 올리기

모범 답안 zip을 새 폴더에 푼 루트에서 실행합니다. 시작 코드는 아래 검사에서 실패하며 실습에서 수정합니다. 기록 비교 단계는 먼저 인덱스에 올리는 단계를 수행합니다.

cp workspace/app.example.env workspace/app.env
bash scripts/record.sh

실행 결과

change recorded in index

예시와 실제 설정 구분

모범 답안 zip을 새 폴더에 푼 루트에서 실행합니다. 시작 코드는 아래 검사에서 실패하며 실습에서 수정합니다. 기록 비교 단계는 먼저 인덱스에 올리는 단계를 수행합니다.

cp workspace/app.example.env workspace/app.env
git ls-files workspace
git check-ignore workspace/app.env

실행 결과

workspace/app.example.env
workspace/app.env

기록과 안내 검사

모범 답안 zip을 새 폴더에 푼 루트에서 실행합니다. 시작 코드는 아래 검사에서 실패하며 실습에서 수정합니다. 기록 비교 단계는 먼저 인덱스에 올리는 단계를 수행합니다.

cp workspace/app.example.env workspace/app.env
bash check.sh

실행 결과

PASS example config exists
PASS record command
PASS secret fixtures excluded
PASS reviewable files staged
PASS readme environment commands evidence
PASS staged diff visible
RESULT: 0 failure(s)

확인 문제

실습

시작 코드 zip을 개인 폴더에 풀고 README를 읽은 뒤 bash check.sh로 실패 항목을 확인합니다. scripts/record.sh와 .gitignore를 고쳐 공개 예시·스크립트·README만 검토 대상으로 올립니다. 실제 설정과 가짜 비밀을 제외하고 커밋이나 원격 전송 없이 인덱스 차이를 확인합니다. 검사기는 복사본에서 정상·경계 상황을 확인합니다. check.sh와 check.py는 수정하지 않습니다.

시작 코드·테스트 내려받기

실행 명령

bash check.sh

기대 결과

모든 항목 PASS, RESULT: 0 failure(s), 종료 상태 0

모범 답안모범 답안 내려받기

더 읽기

면접 질문

  • Git 작업 트리와 인덱스의 차이를 설명해 주세요.
  • 이미 추적 중인 비밀 파일에 .gitignore를 추가하면 어떤 일이 일어나나요?