Git은 강력하지만, 복잡한 상황에서는 개발자를 당황하게 만드는 경우가 많습니다. “앗, 방금 뭘 한 거지?” 싶은 순간은 누구에게나 찾아옵니다. 이 글에서는 checkout, stash, branch 등 핵심 명령어를 중심으로, 실제 현업에서 자주 겪는 20가지 트러블 슈팅 사례와 해결 방안을 구체적으로 정리했습니다.
Part 1: checkout 관련 문제 - “코드가 뒤섞였어요!” checkout은 브랜치를 바꾸거나 특정 버전으로 돌아갈 때 사용하지만, 이 과정에서 많은 실수가 발생합니다.
사례 1: 다른 브랜치로 이동하려는데, 작업하던 내용이 있어서 막힐 때 문제 상황: feature/new-login 브랜치에서 작업하던 중, 급하게 hotfix/bug-report 브랜치로 이동해야 합니다. git checkout hotfix/bug-report를 입력하니 “error: Your local changes to the following files would be overwritten by checkout…” 메시지가 나옵니다. 해결 방안: 아직 커밋하기 애매한 작업 내용을 임시 저장 공간(stash)에 저장합니다. # 현재 작업 내용을 스택에 임시 저장 git stash > `git stash`: 현재 작업 디렉터리의 변경된 파일(Tracked files)을 임시로 스택에 저장합니다. `push`, `pop`, `apply`, `list` 등의 하위 명령어를 통해 관리할 수 있습니다. # 원하는 브랜치로 이동하여 작업 수행 git checkout hotfix/bug-report # ... 핫픽스 작업 ... git commit -m "Fix: Critical bug" git push origin hotfix/bug-report # 원래 브랜치로 복귀 git checkout feature/new-login # 임시 저장했던 작업 내용 다시 적용 git stash pop 사례 2: 실수로 파일을 삭제했는데, 커밋은 아직 안 했을 때 (rm a.txt) 문제 상황: git rm이 아닌 rm 명령어로 파일을 삭제했습니다. git status에 “deleted: a.txt"로 표시됩니다. 해결 방안: checkout을 사용해 현재 브랜치(HEAD)의 마지막 커밋 상태에서 해당 파일을 복원합니다. # a.txt 파일을 마지막 커밋 상태로 복원 git checkout HEAD -- a.txt ```bash > `git checkout <commit> -- <file>`: 특정 커밋 상태의 특정 파일을 현재 작업 디렉터리로 복원합니다. `--`는 브랜치/커밋과 파일 경로를 명확하게 구분하는 역할을 합니다. # -- 를 사용하면 브랜치 이름과 파일 이름을 명확히 구분할 수 있어 안전합니다. 사례 3: 브랜치를 옮기지 않고 다른 브랜치의 파일 내용만 보고 싶을 때 문제 상황: 현재 브랜치는 feature인데, main 브랜치의 config.yml 파일 내용과 비교하고 싶습니다. 브랜치를 통째로 옮기기엔 부담스럽습니다. 해결 방안: git show 또는 git checkout을 특정 파일에 대해서만 실행합니다. # 1. git show 사용 (단순 조회) git show main:path/to/config.yml > `git show <branch>:<path/to/file>`: 브랜치를 변경하지 않고, 다른 브랜치에 있는 파일의 내용을 터미널에 출력합니다. # 2. git checkout 사용 (현재 작업 디렉터리로 가져오기) git checkout main -- path/to/config.yml # 위 명령은 `main` 브랜치의 `config.yml`을 현재 디렉터리로 가져와 덮어씁니다. # 주의: 현재 작업 디렉터리의 내용이 변경됩니다. 사례 4: “Detached HEAD” 상태가 되었을 때 문제 상황: git checkout <commit-hash> 나 git checkout origin/main 처럼 브랜치가 아닌 포인터를 직접 체크아웃하면 “You are in ‘detached HEAD’ state.” 라는 메시지가 나옵니다. 이 상태에서 작업하고 커밋하면 해당 커밋은 어떤 브랜치에도 속하지 않게 되어 나중에 잃어버릴 수 있습니다. 해결 방안: 현재 “Detached HEAD” 상태에서 새로운 브랜치를 만들어 작업을 이어갑니다. # 현재 위치에서 'temp-work' 라는 새 브랜치를 생성 git checkout -b temp-work > `git checkout -b <new-branch>`: 현재 위치(커밋)에서 새로운 브랜치를 생성하고, 즉시 해당 브랜치로 전환합니다. # 이제 'temp-work' 브랜치에서 안전하게 커밋을 이어갈 수 있습니다. git add . git commit -m "Add new feature from detached state" 사례 5: 과거의 특정 파일 버전 하나만 현재 브랜치로 가져오고 싶을 때 문제 상황: config.js 파일의 과거 버전이 필요합니다. 3개의 커밋 전(HEAD~3) 버전의 config.js만 현재 작업 내용에 덮어쓰고 싶습니다. 해결 방안: git checkout에 커밋 해시와 파일 경로를 지정합니다. # 3개 커밋 전 버전의 'config.js'를 현재 디렉터리로 가져옴 git checkout HEAD~3 -- src/config.js git checkout <commit> -- <file>: 특정 커밋에 해당하는 파일의 버전으로 현재 작업 디렉터리의 파일을 덮어씁니다.
...