심볼릭 링크 설정으로 시작된 Git 추적 경계 탐구

이건선·2026년 1월 3일

해결

목록 보기
53/66

배경

AI 에이전트가 작업 파일을 분석하도록 설정하는 과정에서 macOS TCC 권한 문제에 반복적으로 막혔다.
Full Disk Access를 부여하지 않으면서도 안정적으로 파일을 읽게 하려면, 에이전트가 접근 가능한 디렉터리에 파일을 두되 Obsidian에서도 편하게 편집할 수 있어야 했다.

그래서 심볼릭 링크를 사용했다.

/Users/igeonseon/obsidian/work/analysis -> /Users/igeonseon/private-data

문제는 이 구조가 Git 저장소 안에 있다는 점이었다.
work 디렉터리를 Git으로 관리하는데, 민감한 데이터가 담긴 private-data가 원격 저장소로 올라가면 안 된다.

심볼릭 링크로 연결된 외부 디렉터리는 Git에 어떻게 인식될까?


개념 분해

역할: 파일 시스템에서 다른 경로를 가리키는 포인터

Git 추적 모델

역할: 작업 트리의 파일 내용을 스냅샷으로 저장

Git은 .git 디렉터리 내부에 파일 내용을 객체로 저장한다. 일반 파일은 내용 전체를, 심볼릭 링크는 링크가 가리키는 "경로 문자열"만을 저장한다.

역할: 앱의 사용자 데이터 접근을 통제하는 보안 프레임워크

Downloads, Documents, Desktop 등 특정 폴더는 앱이 접근하기 전에 명시적 권한이 필요하다.

하지만 사용자가 직접 만든 폴더(~/dev, ~/work 등)는 TCC 보호 대상이 아니다.


상황 재현

초기 구조

/Users/igeonseon/obsidian/work/         (Git 저장소)
└── analysis -> /Users/igeonseon/private-data

work는 Git으로 관리하고, private-data는 TCC 비보호 영역에 두어 AI 에이전트가 자유롭게 읽을 수 있게 했다. 그리고 Obsidian에서는 work/analysis를 통해 편집한다.

Git에 추가

cd /Users/igeonseon/obsidian/work
git add analysis
git commit -m "add analysis"

이때 예상과 달리 private-data 내부 파일은 Git 객체로 추가되지 않았다.

Git이 저장한 내용

$ git ls-tree HEAD
100644 blob abc123... README.md
120000 blob def456... analysis

심볼릭 링크는 파일 모드 120000으로 저장된다. 실제 내용을 확인하면:

$ git show HEAD:analysis
/Users/igeonseon/private-data

Git은 링크가 가리키는 경로 문자열만 저장했다.

동작 원리

1. git add analysis
        ↓
2. Git이 파일 타입 확인 → 심볼릭 링크 감지
        ↓
3. 링크가 가리키는 경로 문자열만 읽음
        ↓
4. 해당 문자열을 blob 객체로 저장 (모드 120000)
        ↓
5. 결과: 외부 데이터는 Git에 포함되지 않음

Git은 심볼릭 링크를 따라가지 않는다.


효과

TCC 우회: AI 에이전트가 권한 문제 없이 파일 읽기 가능
편집 편의성: Obsidian에서 work/analysis 경로로 자연스럽게 수정
보안 유지: Git 원격 저장소에 민감한 데이터 절대 노출 안 됨


핵심 정리

심볼릭 링크 = 경로 문자열만 저장하는 포인터 (실제 데이터 X)
Git 추적 = 링크 자체만 저장, 링크 대상은 절대 추적 안 함
TCC 우회 = 사용자 생성 디렉터리는 보호 대상 제외
profile
멋지게 기록하자

0개의 댓글