Git을 오래 쓰게 만드는 기능은 과거 파일을 꺼내는 것보다 변경의 경로를 읽는 기능에 가깝습니다. 언제 설정이 바뀌었는지, 어떤 브랜치에서 합쳐졌는지 확인할 수 있어요. 문제가 생겼을 때도 최근 커밋을 순서 없이 지우는 대신 원인을 좁힐 수 있습니다.
5편에서 만든 gitops-demo처럼 커밋이 두 개 이상 있는 저장소를 사용합니다. 이 글의 조회 명령은 작업 파일을 바꾸지 않습니다. 체크아웃이나 bisect를 시작하기 전에는 미완료 작업을 커밋하거나 별도로 보관합니다.
Git·GitOps 전체 연재 · 06 / 24
이 글의 목차
전체 그래프와 개별 변경을 따로 본다
git status --short --branch
git log --oneline --graph --decorate --all -15
git show --stat HEAD
git show HEAD -- README.md
git diff HEAD~1 HEAD -- README.md
--graph는 부모 관계를 그려 주고, --decorate는 브랜치나 태그가 가리키는 위치를 표시합니다. 해시가 시간순 번호가 아니므로 글자 크기나 숫자로 먼저 만든 커밋을 판단하지 않습니다. HEAD~1은 현재 커밋의 첫 번째 부모이며 첫 커밋에는 존재하지 않습니다.
특정 파일의 변경을 따라갈 때에는 경로를 지정합니다. -- 뒤는 경로라는 뜻이므로 브랜치 이름과 파일 이름이 겹쳐도 모호함을 줄일 수 있어요.
git log --oneline -- README.md
git log -p -2 -- README.md
git blame README.md
blame은 현재 줄이 어느 커밋에서 왔는지 보여줍니다. 담당자를 비난하거나 버그의 원인을 확정하는 도구는 아닙니다. 줄을 이동하거나 형식을 바꾼 커밋이 표시될 수 있으므로 해당 커밋의 설명과 앞뒤 변경도 읽습니다.
커밋이 그래프가 되는 이유
Git은 파일 내용인 blob, 파일 이름과 구성을 담는 tree, 그 tree와 부모 등을 가리키는 commit 객체를 사용합니다. 커밋은 이전 커밋을 참조하므로 이력이 방향을 가진 비순환 그래프, DAG를 이룹니다. 병합 커밋은 부모를 둘 이상 가질 수 있습니다.
git rev-parse HEAD
git cat-file -t HEAD
git cat-file -p HEAD
직접 본 객체에는 tree, parent, 작성 정보와 메시지가 나타납니다. 객체 ID는 내용에 기반하므로 커밋 메시지나 부모가 바뀌어도 새 ID가 됩니다. 이 때문에 rebase로 변경을 다시 쌓으면 파일 내용이 비슷해도 커밋 해시가 달라집니다.
브랜치는 이 객체를 통째로 복사한 폴더가 아니라 특정 커밋을 가리키는 이름입니다. 보통 HEAD는 현재 브랜치를 가리키며, 새 커밋을 만들면 그 브랜치가 앞으로 이동합니다.
과거 상태를 보기 위한 detached HEAD
git status --porcelain
git switch --detach HEAD~1
# Inspect files here. Do not start unrecorded work.
git switch main
브랜치 대신 커밋을 직접 체크아웃하면 detached HEAD 상태입니다. 이 상태에서도 커밋은 만들 수 있지만, 돌아갈 이름을 만들지 않고 이동하면 찾기 어려워질 수 있어요. 여기서 작업을 보존하려면 이동 전에 git switch -c inspect-fix처럼 브랜치를 만듭니다.
문제가 시작된 커밋을 절반씩 좁힌다
커밋이 수백 개라면 git bisect가 유용합니다. 정상 커밋과 문제 커밋 사이를 나누어 검사하므로 후보를 선형으로 하나씩 읽는 것보다 적은 판단으로 좁힐 수 있습니다. 단, 같은 테스트가 같은 기준으로 성공·실패해야 합니다.
# Replace GOOD_COMMIT with a known-good commit ID.
git bisect start
git bisect bad HEAD
git bisect good GOOD_COMMIT
# Test the selected commit, then mark one result:
git bisect good
# Repeat with good or bad until Git identifies a commit.
git bisect reset
위의 good은 실제 테스트가 통과했을 때만 표시합니다. 자동화는 git bisect run 테스트명령을 사용할 수 있지만, 테스트 실행 불가와 실패를 구분해야 합니다. 아직 이력이 짧다면 지금은 log → show → diff 순서를 익히는 것으로 충분합니다.
객체 구조는 Git Internals: Git Objects, 탐색 방법은 git bisect를 근거로 설명했습니다.
이전 글 · [Git·GitOps 05] 첫 저장소 만들기: add·commit·status·diff를 쓰는 순서 · 다음 글 · [Git·GitOps 07] 되돌리기 전에 고르는 명령: restore·reset·revert · 연재 목록과 예제 파일

![[Git·GitOps 24] Git·CI/CD·GitOps 운영 흐름 완성하기: 장애별 판단과 복구](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-git-photo-12-768x510.webp)
![[Git·GitOps 23] 비밀 값 관리: Secret의 base64와 SOPS·age 암호화](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-git-photo-2-768x512.webp)
![[Git·GitOps 22] 변경 감지와 복구: 자동 Sync·selfHeal·prune·Git revert](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-git-photo-10-768x576.webp)
답글 남기기