Git symlink가 Windows에서 일반 파일처럼 보일 때: 확인과 복구 방법
개발하다 보면 AGENTS.md, CLAUDE.md 같은 파일 안에 단순히 AI_GUIDE.md라고만 적혀 있는 경우를 볼 수 있다.
처음 보면 “그냥 파일명만 적힌 텍스트 파일 아닌가?” 싶지만, Git에서는 이것이 심볼릭 링크일 수 있다.
심볼릭 링크는 단순한 텍스트 파일이 아니라, 다른 파일이나 디렉터리를 가리키는 파일 시스템 레벨의 참조다.
CLAUDE.md -> AI_GUIDE.md
이런 구조라면 CLAUDE.md를 열었을 때 실제로는 AI_GUIDE.md를 따라가게 된다.
문제는 Windows에서 이 symlink가 종종 일반 파일처럼 보인다는 점이다. 특히 AI 가이드 파일처럼 AGENTS.md, CLAUDE.md, AI_GUIDE.md를 함께 운영할 때 이 차이를 모르고 수정하면, 의도치 않게 symlink target 자체를 바꿔 버릴 수 있다.
심볼릭 링크와 일반 파일의 차이
일반 파일은 자기 자신의 내용을 가진다.
CLAUDE.md
내용: AI_GUIDE.md
반면 심볼릭 링크는 다른 경로를 가리킨다.
CLAUDE.md
링크 대상: AI_GUIDE.md
겉보기에는 둘 다 AI_GUIDE.md라는 문자열을 보여줄 수 있지만, 의미는 완전히 다르다.
일반 파일의 AI_GUIDE.md는 그냥 텍스트다. 사람이든 AI든 “이 파일을 읽으라는 뜻인가?”라고 해석해야 한다.
반면 심볼릭 링크의 AI_GUIDE.md는 파일 시스템이 이해하는 링크 대상이다.
즉 핵심 차이는 다음과 같다.
일반 파일: AI_GUIDE.md라는 문자열을 내용으로 가진 파일
심볼릭 링크: AI_GUIDE.md라는 경로를 가리키는 링크
Git에서 심볼릭 링크는 어떻게 저장될까
Git은 심볼릭 링크를 특별한 파일 모드로 저장한다. 확인 명령은 다음과 같다.
git ls-files -s -- CLAUDE.md
출력에 120000이 보이면 Git 기준으로는 심볼릭 링크다.
120000 c6799b9b... 0 CLAUDE.md
반대로 일반 파일이면 보통 100644가 나온다.
100644 d473937... 0 CLAUDE.md
즉 Git에서 중요한 구분은 다음과 같다.
120000 = symbolic link
100644 = regular file
여기서 중요한 점은 Git이 보는 기준과 작업 폴더에서 눈에 보이는 모습이 다를 수 있다는 것이다. 특히 Windows에서는 이 차이가 자주 드러난다.
Windows에서 왜 일반 파일처럼 보일까
macOS와 Linux에서는 심볼릭 링크가 자연스럽게 동작한다. ln -s로 만들고, Git에서도 대부분 문제 없이 체크아웃된다.
문제는 Windows다. Windows도 심볼릭 링크를 지원하지만, Git 설정과 권한에 따라 체크아웃 결과가 달라질 수 있다.
특히 core.symlinks=false이면 Git은 심볼릭 링크를 실제 Windows symlink로 만들지 않고, 링크 대상 경로가 들어 있는 작은 일반 파일처럼 체크아웃할 수 있다.
예를 들어 Git index에는 다음처럼 기록되어 있어도:
CLAUDE.md -> AI_GUIDE.md
Windows 작업 폴더에서는 CLAUDE.md라는 일반 파일 안에 다음 문자열만 들어 있는 것처럼 보일 수 있다.
AI_GUIDE.md
이 지점이 헷갈림의 핵심이다.
Git 기준: symlink
Windows 작업 폴더 기준: 일반 파일처럼 보임
따라서 Windows에서는 Git 기준과 실제 파일 시스템 기준을 나눠서 확인해야 한다.
Windows에서 symlink인지 확인하고 복구하는 방법
Windows에서는 두 가지를 따로 확인해야 한다.
첫째, Git이 해당 파일을 symlink로 추적하고 있는지 확인한다.
둘째, Windows 작업 폴더에 실제 symlink로 만들어져 있는지 확인한다.
1. Git 기준으로 확인하기
먼저 Git index에 기록된 파일 모드를 확인한다.
git ls-files -s -- CLAUDE.md
출력 앞이 120000이면 Git 기준으로 symlink다.
120000 c6799b9b... 0 CLAUDE.md
일반 파일이면 보통 100644가 나온다.
100644 d473937... 0 CLAUDE.md
즉 Git 기준의 핵심 구분은 다음과 같다.
120000 = symbolic link
100644 = regular file
여러 파일을 한 번에 확인하려면 다음처럼 실행할 수 있다.
git ls-files -s -- AGENTS.md CLAUDE.md
2. Windows 작업 폴더 기준으로 확인하기
그 다음 Windows 파일 시스템에서 실제 symlink로 존재하는지 확인한다.
Get-Item .\CLAUDE.md | Select-Object LinkType, Target, Length
실제 symlink라면 다음처럼 LinkType과 Target이 보인다.
LinkType Target Length
-------- ------ ------
SymbolicLink {AI_GUIDE.md} 0
반대로 LinkType이 비어 있고, Length가 11처럼 나오며 파일 내용이 AI_GUIDE.md라면 Git상 symlink가 Windows 작업 폴더에서는 일반 파일처럼 풀린 상태일 수 있다.
Git index: symlink
Windows working tree: plain file
이 상태에서는 파일이 일반 텍스트 파일처럼 보이지만, Git이 여전히 120000 symlink로 추적하고 있다면 그 한 줄은 파일 내용이 아니라 symlink target으로 취급될 수 있다.
3. Git 설정 확인하기
현재 repository의 symlink 설정을 확인한다.
git config --show-origin --get core.symlinks
false라면 Git이 symlink를 실제 Windows symlink로 체크아웃하지 않는 설정이다.
file:.git/config false
값이 나오지 않는다면 해당 scope에 명시적으로 설정된 값이 없다는 뜻이다. 이 경우에도 현재 작업 폴더에서 실제 symlink가 만들어졌는지는 Get-Item으로 다시 확인해야 한다.
4. 실수로 symlink target을 바꾼 변경 되돌리기
Windows에서 symlink가 일반 파일처럼 보이는 상태에서 CLAUDE.md를 다음처럼 수정했다고 하자.
Read `AI_GUIDE.md`.
Git이 여전히 이 파일을 120000 symlink로 추적하고 있다면, 이 변경은 일반 파일 내용 변경이 아니라 symlink target 변경으로 기록될 수 있다.
변경 전: CLAUDE.md -> AI_GUIDE.md
변경 후: CLAUDE.md -> Read `AI_GUIDE.md`.
이런 링크는 당연히 깨진 링크가 된다.
아직 commit하지 않았다면 먼저 변경을 되돌린다.
git restore --staged --worktree -- CLAUDE.md AGENTS.md
이 명령은 해당 파일들의 staged 변경과 working tree 변경을 모두 되돌린다. 따라서 필요한 변경이 섞여 있다면 먼저 다른 곳에 백업하거나 별도로 저장해야 한다.
5. Windows 작업 폴더에서도 실제 symlink로 복구하기
Windows 작업 폴더에서도 실제 symlink로 만들고 싶다면 먼저 Windows Developer Mode를 켜거나, 관리자 권한 셸을 사용해야 한다.
그 다음 repository 설정을 바꾼다.
git config core.symlinks true
이미 일반 파일처럼 풀려 있는 symlink 파일은 다시 체크아웃해야 한다. 먼저 변경 사항이 없는지 확인한다.
git status --short -- CLAUDE.md AGENTS.md
출력이 비어 있다면 해당 파일들에 작업 중인 변경이 없다는 뜻이다.
그 다음 기존 파일을 지우고 Git index 기준으로 다시 복원한다.
Remove-Item -Force .\CLAUDE.md, .\AGENTS.md
git restore --worktree -- CLAUDE.md AGENTS.md
하위 디렉터리까지 포함한다면 대상 파일을 명시적으로 모아 처리한다.
$paths = @(
"AGENTS.md",
"CLAUDE.md",
"arcana_client/AGENTS.md",
"arcana_client/CLAUDE.md",
"arcana_server/AGENTS.md",
"arcana_server/CLAUDE.md",
"arcana_shared/AGENTS.md",
"arcana_shared/CLAUDE.md"
)
git status --short -- $paths
# 위 명령 출력이 비어 있을 때만 실행한다.
Remove-Item -Force $paths
git restore --worktree -- $paths
복구 후 다시 확인한다.
Get-Item .\CLAUDE.md | Select-Object LinkType, Target, Length
LinkType이 SymbolicLink이고 Target이 {AI_GUIDE.md}라면 Windows 작업 폴더에서도 symlink로 정상 복구된 것이다.
6. 새로 clone할 때 symlink 설정 켜기
새로 clone할 수 있다면 clone 시점에 symlink 설정을 켜는 방법도 있다.
git clone -c core.symlinks=true <repo-url>
단, 이 방식도 Windows에서 실제 symlink를 만들 권한이 준비되어 있어야 한다. 즉 Developer Mode를 켜거나 관리자 권한 셸에서 실행하는 것이 안전하다.
checkout 시점부터 symlink가 실제 링크로 만들어지므로, 가능하다면 새 clone이 가장 깔끔한 방법이다.
AI 가이드 파일에서 생기는 문제
예를 들어 Git에는 다음과 같은 symlink가 있다고 하자.
CLAUDE.md -> AI_GUIDE.md
AGENTS.md -> AI_GUIDE.md
macOS/Linux에서는 CLAUDE.md를 열면 자연스럽게 AI_GUIDE.md를 보게 된다.
하지만 Windows에서 symlink가 일반 파일처럼 체크아웃되면 CLAUDE.md 내용이 이렇게 보일 수 있다.
AI_GUIDE.md
이 상태에서 누군가 파일을 수정해 다음처럼 바꾸면 문제가 생긴다.
Read `AI_GUIDE.md`.
의도는 “AI에게 이 파일을 읽으라고 안내하는 일반 파일”이었을 수 있다. 하지만 Git이 아직 해당 파일을 symlink로 보고 있다면, 이 변경은 일반 파일 내용 변경이 아니라 symlink 대상 변경처럼 해석될 수 있다.
즉 의도는 이것이었는데:
CLAUDE.md 파일 내용 = Read `AI_GUIDE.md`.
실제로는 이렇게 될 위험이 있다.
CLAUDE.md -> Read `AI_GUIDE.md`.
이 문제는 diff만 봐서는 더 헷갈릴 수 있다. git diff에는 단순히 한 줄 텍스트가 바뀐 것처럼 보이지만, Git mode가 여전히 120000이면 그 한 줄은 파일 내용이 아니라 symlink target이다.
따라서 이런 파일을 수정하기 전에는 항상 다음 명령으로 mode를 먼저 확인하는 것이 안전하다.
git ls-files -s -- CLAUDE.md AGENTS.md
정리하면 다음과 같다.
120000이면: 그 문자열은 symlink target
100644이면: 그 문자열은 일반 파일 내용
Windows에서 CLAUDE.md가 한 줄짜리 텍스트 파일처럼 보인다고 해서 곧바로 일반 안내 파일이라고 판단하면 안 된다. 중요한 것은 파일에 보이는 문자열이 아니라 Git이 기록한 mode다.
@AI_GUIDE.md는 무엇인가
일부 AI 도구나 IDE에서는 @AI_GUIDE.md 같은 문법을 파일 멘션으로 처리한다. 사용자가 프롬프트에 @파일명을 쓰면 해당 파일을 컨텍스트에 포함하는 방식이다.
하지만 이것은 Markdown 표준도 아니고 Git 기능도 아니다. 도구별 편의 문법이다.
비교하면 다음과 같다.
AI_GUIDE.md
symlink라면 링크 대상이다. 일반 파일이라면 그냥 텍스트다.
@AI_GUIDE.md
일부 AI 도구가 파일 참조로 해석할 수 있다. 모든 도구에서 통하지는 않는다.
Read `AI_GUIDE.md`.
가장 범용적인 안내문이다. 파일 시스템 링크는 아니지만, 사람과 AI 모두 의미를 이해하기 쉽다.
언제 symlink를 쓰고, 언제 일반 파일을 쓸까
macOS/Linux 중심의 개발 환경이고 팀이 symlink에 익숙하다면 symlink는 좋은 선택이다. 중복이 없고, AI_GUIDE.md 하나만 관리하면 된다.
AGENTS.md -> AI_GUIDE.md
CLAUDE.md -> AI_GUIDE.md
하지만 Windows 사용자가 많거나, 여러 AI 도구와 에디터가 섞여 있다면 일반 파일이 더 안전할 수 있다.
Read `AI_GUIDE.md`.
이 방식은 파일 시스템 링크에 의존하지 않는다. 대신 사람이나 AI 도구가 이 문장을 읽고 AI_GUIDE.md를 다시 열어야 한다.
선택 기준은 다음처럼 정리할 수 있다.
symlink 유지가 적합한 경우
- macOS/Linux 중심 개발 환경이다.
- 팀이 symlink 동작을 이해하고 있다.
- 중복 파일을 만들고 싶지 않다.
- Windows 사용자는 Developer Mode 또는 관리자 권한 설정을 맞출 수 있다.
일반 안내 파일이 적합한 경우
- Windows 사용자가 많다.
- 여러 AI 도구, IDE, 에디터가 섞여 있다.
- 파일 시스템 링크보다 명시적인 안내문이 더 중요하다.
- 약간의 중복보다 호환성과 예측 가능성이 더 중요하다.
symlink를 쓰지 않고 일반 안내 파일로 전환하려면
팀에 Windows 사용자가 많거나, 여러 AI 도구와 에디터가 섞여 있다면 symlink를 포기하고 일반 안내 파일로 바꾸는 편이 더 단순할 수 있다.
이때 중요한 점은 단순히 symlink처럼 보이는 파일 내용을 수정하는 것이 아니라, Git mode 자체를 120000에서 100644로 바꾸는 것이다.
예를 들어 AGENTS.md, CLAUDE.md를 일반 안내 파일로 바꾸려면 다음처럼 한다.
git rm -- AGENTS.md CLAUDE.md
Set-Content -Path .\AGENTS.md -Value 'Read `AI_GUIDE.md`.' -Encoding utf8
Set-Content -Path .\CLAUDE.md -Value 'Read `AI_GUIDE.md`.' -Encoding utf8
git add -- AGENTS.md CLAUDE.md
git ls-files -s -- AGENTS.md CLAUDE.md
출력이 100644로 바뀌었는지 확인한다.
100644 ... AGENTS.md
100644 ... CLAUDE.md
하위 디렉터리에 있는 안내 파일도 일반 파일로 바꿀 수 있다. 다만 이 경우 AI_GUIDE.md의 위치에 따라 안내 문구의 상대 경로를 조정해야 한다.
예를 들어 하위 디렉터리에서 루트의 AI_GUIDE.md를 가리켜야 한다면 다음처럼 쓰는 편이 더 명확하다.
Read `../AI_GUIDE.md`.
이 방식은 파일 시스템 symlink에 의존하지 않는다. 대신 사람과 AI 도구가 문장을 읽고 AI_GUIDE.md를 다시 열어야 한다.
결론
심볼릭 링크는 “파일명만 적힌 이상한 파일”이 아니다. Git과 파일 시스템이 이해하는 진짜 링크다.
하지만 Windows에서는 core.symlinks 설정과 권한 때문에 symlink가 실제 링크가 아니라 링크 대상 경로를 담은 작은 일반 파일처럼 보일 수 있다. 이 상태에서 파일을 편집하면 의도치 않게 symlink target 자체를 바꾸는 diff가 생길 수 있다.
따라서 저장소에서 AGENTS.md, CLAUDE.md 같은 AI 가이드 파일을 운영할 때는 둘 중 하나를 명확히 선택해야 한다.
선택 1: symlink 유지
- Git mode: 120000
- 내용: AI_GUIDE.md 같은 link target
- 장점: 중복 관리가 없다
- 주의: Windows에서는 Developer Mode, 관리자 권한, core.symlinks 설정 확인 필요
선택 2: 일반 안내 파일로 전환
- Git mode: 100644
- 내용: Read `AI_GUIDE.md`.
- 장점: Windows, 에디터, AI 도구 호환성이 좋다
- 주의: AI_GUIDE.md를 자동으로 따라가는 파일 시스템 링크는 아니다
중요한 것은 AI_GUIDE.md라는 문자열 자체가 아니다. 그 파일이 Git에서 120000 symlink인지, 100644 일반 파일인지 확인하는 것이다.
심볼릭 링크를 다룰 때는 항상 먼저 다음 명령을 실행하자.
git ls-files -s -- AGENTS.md CLAUDE.md
Windows에서는 여기에 실제 파일 시스템 확인도 추가하면 더 안전하다.
Get-Item .\CLAUDE.md | Select-Object LinkType, Target, Length
이 두 가지를 확인하면 “Git 기준으로는 symlink인데 Windows에서는 일반 파일처럼 보이는” 혼란을 대부분 피할 수 있다.
'TIL(Today I Learn) > TIL' 카테고리의 다른 글
| Codex GPT-5.6 Sol `collaboration.spawn_agent` 오류 우회: 멀티 에이전트를 끄지 않고 고치는 방법 (1) | 2026.07.10 |
|---|---|
| 바이브 코딩 중인 내가 쓰는 Agent Skills - 260611 (0) | 2026.06.02 |
| 구조체 패킷의 한계와 직렬화 버퍼(Serialization Buffer)가 필요한 이유 (0) | 2026.02.19 |
| 메모리 풀과 프리리스트 – 고정 크기 객체의 Alloc/Free를 빠르게 만드는 방법 (0) | 2026.02.19 |
| 링버퍼(Ring Buffer) - 원활한 통신을 위한 자료구조 (0) | 2026.02.19 |