이 글은 Today I Learn 시리즈의 110번째 기록입니다. (총 125개)

이 블로그는 Obsidian으로 마크다운을 쓰는데, repo가 vault 안에 통째로 들어 있어서 node_modules·src 같은 코드까지 Obsidian이 인덱싱하고 있었다. 검색이 코드에 다 묻혔다. “코드는 vault에서 빼고 포스트만 남기고 싶다”를 푸는 과정을 정리한다.


못 하는 것부터 — 코드와 콘텐츠는 한 repo여야 한다

먼저 “코드 폴더만 딴 데로 옮기고 포스트만 남기기”는 안 된다. 빌드가 둘을 한 덩어리로 보기 때문이다.

  • Astro는 ./_content를 repo 루트 기준 상대경로로 읽는다
  • Cloudflare Pages는 그 repo 하나를 통째로 빌드한다

그래서 _content와 코드가 서로 다른 폴더·repo로 갈라지면 빌드가 깨진다. 결론은 분리하지 말고 “보이는 범위”만 좁히자였다.


junction — 프로그램이 진짜 폴더처럼 따라가는 별칭

바로가기(.lnk)와 무엇이 다른가

핵심 도구가 directory junction이다. 일반 바로가기(.lnk)는 “저기로 가라”고 적힌 쪽지라, 탐색기 더블클릭엔 반응해도 프로그램한테 “여기 폴더야” 하면 못 따라간다. junction은 파일시스템 수준에서 “이 경로 = 저 폴더”라고 못 박은 거라, 프로그램(Obsidian 포함)이 열면 진짜 그 폴더 내용이 나오고 읽기·쓰기가 다 된다. 복사본이 아니라 입구 둘, 방 하나다.

그래서 repo는 vault 밖으로 통째로 옮기고, vault 안엔 _content를 가리키는 junction만 두면 — Obsidian은 포스트만 보고(코드는 안 보임), 글을 쓰면 진짜 repo의 _content가 바뀌어 git·빌드가 그대로 먹는다.

만들기

관리자 권한이 필요 없다(심볼릭 링크와 달리 junction은 권한 불필요).

# repo 통째로 이동 (같은 드라이브면 즉시)
Move-Item -LiteralPath $src -Destination $dst
# vault 옛 경로에 _content 만 되비추기
New-Item -ItemType Junction -Path "$src\_content" -Target "$dst\_content"

_content를 이렇게 걸면 포스트의 vault 경로(...\kimlog0415.github.io\_content\...)가 이전과 똑같이 유지된다. Obsidian 링크·검색 인덱스가 안 깨진다.


Obsidian 쪽에서 알게 된 것

vault가 코드까지 인덱싱하면 검색이 오염된다

검색을 덮은 진짜 범인은 node_modules였다. 거기 README.md가 수천 개라 검색 결과를 다 잡아먹는다. junction까지 안 가고 가볍게 끝내려면 방법이 세 가지다.

  • Excluded files(설정 → 파일 및 링크): 코드 폴더 경로를 넣으면 검색·퀵스위처·그래프에서 빠진다. repo 구조는 안 건드림
  • vault를 _content로 전환: vault가 블로그 전용이면 됨. 다른 노트도 섞인 vault면 불가
  • junction: 폴더 트리에서까지 코드를 아예 안 보이게 하고 싶을 때

점(.)으로 시작하는 폴더(.git·.astro)는 Obsidian이 자동으로 무시한다.

Obsidian Sync는 “앱이 감지한 변경”만 올린다

파일을 편집기가 아니라 파일시스템에서 직접 고치면(스크립트 등), Obsidian Sync가 바로 안 밀어준다. Sync는 데스크톱 Obsidian 앱이 그 변경을 읽어야 서버로 올리고, 그래야 모바일이 내려받는다. vault가 무거우면 앱의 파일 감시가 느려 이 지연이 더 커진다. 밖에서 고친 게 모바일에 안 뜨면, 데스크톱 앱에서 그 노트를 한 번 열어 주면 그때 올라간다.


옮기다 밟은 것

잠긴 폴더는 이동이 막힌다

Move-Itemused by another process로 실패했다. 폴더를 붙잡고 있는 프로세스가 있으면 이름 바꾸기(이동)가 안 된다 — Obsidian(인덱싱), GitHub Desktop(폴더 감시), 그리고 그 폴더를 작업 디렉터리로 둔 셸까지. 그 폴더를 여는 것들을 다 닫아야 이동이 된다.

위험한 이동 전엔 백업부터

되돌리기 번거로운 파일 작업 전에 두 층으로 백업했다.

git push                                   # 추적 파일은 원격에
find _content -iname "draft-*.md" \
  | tar --force-local --null -czf backup.tar.gz -T -   # gitignore된 draft는 tar로

node_modulesnpm install로 복구되니 백업할 필요가 없다. tarC: 경로를 원격 호스트로 오해하면 --force-local을 붙인다.

git 원격은 로컬 위치와 독립이다

로컬 폴더를 어디로 옮기든 git 원격 주소(remote)는 안 바뀐다. Cloudflare Pages는 그 원격(GitHub)에 연결돼 빌드하므로, 로컬 이동은 배포에 아무 영향이 없다. (반대로 GitHub 계정 자체를 옮기는 것은 별개다 — 그건 원격이 바뀌니 Cloudflare 연결을 새 repo로 다시 이어야 한다.)


정작 제일 중요한 교훈

도구는 그 repo를 root로 열어야 한다

옮기고 나서 편집기·Claude Code를 그 repo 폴더 자체를 root로 열지 않으면 방향을 잃는다. 상위 폴더나 옆 프로젝트를 root로 열면 블로그가 하위로 묻혀서 “왜 안 잡히지”가 된다. 이동 안내에 이걸 같이 적어 두지 않으면, 옮긴 뒤 도구가 엉뚱한 root로 떠서 다 옮긴 게 망가진 것처럼 보인다.

붙어 있어야 하는 건 쪼개지 말고, 뷰만 바꾼다

빌드가 한 덩어리로 봐야 하는 것(코드+콘텐츠)을 물리적으로 나누려 하면 파이프라인이 깨진다. 실제로 필요한 건 “안 보이게 하기”였는데, 그건 파일을 옮기지 않고 보이는 범위(Excluded files·junction)로 푸는 문제였다. 구조를 건드리기 전에 “정말 물리적으로 나눠야 하나, 뷰만 좁히면 되나”를 먼저 가른다.


Series: Today I Learn

1 C++ 자료형(Data Type) 2 MD5 vs pHash 3 C++에서 함수의 선언과 정의 4 Tkinter padx, pady 5 메모리와 포인터 변수 6 Call by Value, Call by Reference, Call by Pointer 비교 7 const 8 Gemfile — Jekyll 프로젝트의 의존성 파일 9 kramdown-parser-gfm — Jekyll의 GFM 파서 10 파서(Parser) 11 AHU vs OHU 12 I might try it vs I'll try it 뉘앙스 차이 13 SESSION_EXPIRE_AT_BROWSER_CLOSE=True 14 configuration key 15 Git stash vs discard 16 subprocess.Popen으로 Windows 탐색기에 명령어를 전달 17 Post 잔디 분석하기 18 Google Sheets Sync 최적화 19 DSL (Domain Specific Language)과 GPL (General Purpose Language) 20 마크다운 표 그리는 방법 21 쿼리 파라미터(Query Parameter). 기존 QR코드 재활용 22 Django 보안 취약점 점검 및 수정 23 OOP Object-Oriented Programming 객체 지향 프로그래밍 24 Fernet 대칭 암호화 25 Jekyll 코드블록 안의 Liquid 태그 26 insertOnConflictUpdate vs DoUpdate(target) 27 세션 필터 28 아코디언(Accordiaon) UI를 펼친상태로 만들기 29 input의 step 30 Word Cloud 31 Google Sheets를 데이터 버스로(with AppSheet) 32 Django 모델 텍스트 필드 자동 수집 패턴 33 localStorage로 섹션 토글 상태 유지 34 순차 ID 생성(`select_for_update()` + `max()` 조합) 35 역참조 검색과 distinct() 36 xlsx 다운로드와 로딩 오버레이 충돌 37 Android 파일 공유 MIME 타입 38 AssetManifest — Flutter 빌드 타임 asset 목록 런타임 조회 39 UTF-8 BOM과 PowerShell 파일 쓰기 40 소리꽃 KeyBloom TIL 1 41 소리꽃 KeyBloom TIL 2 42 소리꽃 KeyBloom TIL 3 43 메트로놈 Simple Metronome TIL 1 44 소리꽃 KeyBloom TIL 4 45 메트로놈 Simple Metronome TIL 2 46 소리꽃 KeyBloom TIL 5 47 메트로놈 Simple Metronome TIL 3 48 정적 블로그 SEO 정비와 Pagefind 검색 도입 49 메트로놈 Simple Metronome TIL 4 50 안드로이드 AudioTrack 연속 재생, 실측 피커 정렬, 카메라 토치 플래시 51 메트로놈 Simple Metronome TIL 5 52 모래게임 Sandrop TIL 1 53 메트로놈 Simple Metronome TIL 6 54 모래게임 Sandrop TIL 2 55 모래게임 Sandrop TIL 3 56 메트로놈 Simple Metronome TIL 7 57 모래게임 Sandrop TIL 4 58 모래게임 Sandrop TIL 5 59 모래게임 Sandrop TIL 6 60 소리꽃 KeyBloom TIL 6 61 모래게임 Sandrop TIL 7 62 모래게임 Sandrop TIL 8 63 소리꽃 KeyBloom TIL 7 64 모래게임 Sandrop TIL 9 65 소리꽃 KeyBloom TIL 8 66 모래게임 Sandrop TIL 10 67 소리꽃 KeyBloom TIL 9 68 소리꽃 KeyBloom TIL 10 69 소리꽃 KeyBloom TIL 11 70 소리꽃 KeyBloom TIL 12 71 소리꽃 KeyBloom TIL 13 72 온실 GreenHouse TIL 1 73 소리꽃 KeyBloom TIL 14 74 온실 GreenHouse TIL 2 75 소리꽃 KeyBloom TIL 15 76 소리꽃 KeyBloom TIL 16 77 소리꽃 KeyBloom TIL 17 78 소리꽃 KeyBloom TIL 18 79 소리꽃 KeyBloom TIL 19 80 소리꽃 KeyBloom TIL 20 81 로그스톤 상표 셀프 출원 TIL 1 82 소리꽃 KeyBloom TIL 21 83 소리꽃 KeyBloom TIL 22 84 소리꽃 KeyBloom TIL 23 85 소리꽃 KeyBloom TIL 24 86 MiniMacro TIL 1 87 Astro가 무엇인지, 왜 옮기는지 88 MiniMacro TIL 2 89 메트로놈 Simple Metronome TIL 8 90 메트로놈 Simple Metronome TIL 9 91 블로그 Astro 이관 TIL 92 오픈데이 Openday TIL 1 93 오픈데이 Openday TIL 2 94 Unreal Engine MCP TIL 1 95 콘티온 Conti On TIL 11 96 오픈데이 Openday TIL 3 97 오픈데이 Openday TIL 4 98 오픈데이 Openday TIL 5 99 ScorePlayer TIL 1 100 BuildingHub TIL 1 101 ScorePlayer TIL 2 102 BuildingHub TIL 2 103 ScorePlayer TIL 3 104 Unreal Engine MCP TIL 2 105 궁 미로 PalaceMaze TIL 1 106 메트로놈 Simple Metronome TIL 10 107 메트로놈 Simple Metronome TIL 11 108 오픈데이 Openday TIL 6 109 BuildingHub TIL 3 110 Obsidian vault에서 코드만 빼기 — directory junction 읽는 중 111 ScorePlayer TIL 4 112 오픈데이 Openday TIL 7 113 URL은 바뀔 수 있는 것에 묶지 않는다 114 도구는 기능이 아니라 내 일에 맞는지로 고른다 115 돌이키기 힘든 변경은 작게 먼저 확인한다 116 궁 미로 PalaceMaze TIL 3 117 궁 미로 PalaceMaze TIL 2 118 소리꽃 KeyBloom TIL 29 119 오픈데이 Openday TIL 8 120 BuildingHub TIL 4 121 ScorePlayer TIL 5 122 BuildingHub TIL 5 123 MiniMacro TIL 3 124 소리꽃 KeyBloom TIL 30 125 궁 미로 PalaceMaze TIL 4