코드가 변해온 길을 따라 읽기
오픈소스를 공부할 때 git history를 따라 코드가 어떻게 변해왔는지 읽는 것은 좋은 방법입니다.
다만 git show는 변경분만 보여주고, tig는 log 탐색에 탁월하지만 파일을 읽기에는 조금 불편하고,
GitHub은 커밋을 넘길 때마다 브라우저를 오가야 합니다.
gluck은 git history를 타임라인으로 삼습니다. 각 시점의 파일 트리를 열고, 파일을 읽고, 이웃한 커밋과 비교하는 일을 터미널 안에서 키보드만으로 할 수 있게 하는 것이 목표입니다. 마우스 휠과 클릭도 지원합니다.
바이너리 이름 glc는 home row 근처에서 편하게 칠 수 있도록 고른 이름입니다.
세 가지 모드
Pick ──Enter──→ View ──Tab──→ Diff ↑ ↑ │ │ └────Tab─────┘ └─── Esc/h ─────────────────┘
커밋 고르기
커밋 리스트와 인라인 diff 미리보기를 함께 봅니다. 커밋을 200개씩 나눠 불러오므로 큰 저장소에서도 첫 화면이 빠르게 뜹니다.
그 시점의 코드 읽기
선택한 커밋 시점의 파일 트리와 내용을 보여줍니다. 폴더 접기, gitignore 필터, 신택스 하이라이트, 줄 번호를 지원합니다.
나란히 비교하기
부모 커밋과 side-by-side로 비교하고, v로 unified 보기로 바꿀 수 있습니다. 긴 줄은 양쪽 패널을 맞춰 줄바꿈합니다.
단어가 기억나지 않아도 찾을 수 있도록
s를 누르면 커밋 메시지, 파일 내용, 함수 이름을 뜻으로 검색합니다.
"인덱스 스키마가 바뀌면 재빌드하던 그 커밋"처럼 정확한 단어가 떠오르지 않을 때 쓰기 좋습니다. 키워드 검색과 의미 검색을 함께 사용해 관련도가 높은 결과를 위로 올립니다.
| s | 어느 모드에서든 검색 모달 열기 |
| 입력 | 커밋, 파일, 심볼을 한 번에 검색합니다. 한국어와 영어를 섞어 써도 됩니다. |
| ^N / ^P | 결과 이동 |
| Enter | 커밋은 Pick으로, 파일과 심볼은 해당 커밋의 View로 이동 |
| I | 인덱스가 없거나 오래되었으면 모달 안에서 다시 빌드 |
| Esc | 닫기 |
동작 방식
glc index는 HEAD의 파일을 tree-sitter로 심볼 단위로 나누고, 커밋 메시지와 함께
BM25 인덱스와 256차원 벡터 인덱스에 저장합니다. 질의는 두 인덱스를 함께 거친 뒤 RRF로 순위를 합칩니다.
- 한국어는 형태소 사전 대신 character bigram으로 처리합니다.
- 영문 오타를 보정합니다.
build_index_incremntal로 검색하면incremental도 함께 찾습니다. 올바른 단어는 그대로 둡니다. - 저장소와 관련이 적은 질문에는 결과 제목에
· no strong match가 표시됩니다. 결과는 그대로 보여주므로 판단은 사용자에게 맡깁니다. path:"src/search/rrf.rs"처럼 경로를 한정하거나,"rrf.rs fuse"처럼 파일명과 함수명으로 좁힐 수 있습니다.- 커밋은 메시지와 함께 변경된 파일 경로도 임베딩합니다. "레이아웃 고친 커밋"으로
src/ui/layout.rs를 수정한 커밋을 찾을 수 있습니다. glc ignore로 만든.glcignore(.gitignore와 같은 문법)로vendor/나 생성된 리포트를 인덱스에서 뺄 수 있습니다. 파일을 바꾸면 다음glc index에서 다시 빌드합니다.- HEAD가 바뀌면 바뀐 부분만 증분 인덱싱합니다. 스키마가 바뀐 경우에는
meta.toml로 감지해 전체를 다시 빌드합니다. - 처음
glc index를 실행할 때 임베딩 모델(약 500MB)을 HuggingFace 캐시로 내려받습니다. glc report로 MRR, Recall@k, NDCG@10과 지연시간 p50/p95/p99를 확인할 수 있습니다. 검색 품질 변화를 숫자로 추적하는 데 씁니다.
.glc-index/는 .gitignore에 추가해 두시길 권합니다. 인덱스 파일이 커밋되면 다음 인덱싱 대상에 섞일 수 있습니다.설치
$ brew tap soomtong/tap && brew install glc$ cargo install --git https://github.com/soomtong/gluck$ glc index사용법
$ glc # 현재 디렉토리의 git history 열기 $ glc /path/to/repo # 특정 저장소 열기 $ glc index # 시맨틱 검색 인덱스 빌드 (.glc-index/) $ glc index --force # 인덱스 강제 재빌드 $ glc ignore # 기본 제외 목록으로 .glcignore 생성 $ glc report # 검색 품질 + 성능 리포트
키 바인딩
vim에 익숙하다면 대부분 예상한 대로 동작합니다.
공통
| j k ↑ ↓ | 이동 |
| ^N / ^P | 이전(older) / 다음(newer) 커밋, 선택한 파일 유지 |
| s | 시맨틱 검색 모달 |
| ^T | 테마 순환 (설정에 저장) |
| Tab | View ⇄ Diff |
| Esc | Pick으로 돌아가기 |
| ^D | 디버그 오버레이 |
| q / ^C | 종료 |
Pick
| Enter / l | 선택한 커밋을 View로 |
| Tab | 선택한 커밋을 Diff로 |
| / | 메시지·작성자·해시 prefix 검색 |
| ^F / ^B | 페이지 이동 |
Diff
| h l ← → | 변경 파일 이동 |
| v | side-by-side ⇄ unified |
| u / d, J / K | 스크롤 / 페이지 |
| w | word wrap 토글 |
View
| Enter | 파일 열기 / 폴더 접기·펼치기 |
| h / l | 폴더 접기(→부모) / 펼치기(→첫 자식) |
| H / L | 이전 / 다음 변경 파일(*)로 이동 |
| . | .gitignore 필터 토글 |
| u / d | 내용 스크롤 (기본 3줄) |
| J / K | 내용 페이지 스크롤 |
| w | word wrap 토글 (기본 on) |
| Esc / h | 파일 위에서 Pick으로 |
시맨틱 검색 모달의 키는 시맨틱 검색 섹션에 정리되어 있습니다.
신택스 하이라이트
tree-sitter 기반으로 다음 언어를 지원합니다. 목록에 없는 확장자는 plain text로 표시합니다.
- Rust
- Go
- C
- JavaScript
- TypeScript
- TSX
- Swift
- Zig
- Bash
- JSON
- YAML
- Markdown
- Assembly
- Linker script
- Lisette
테마와 설정
테마는 여섯 가지이며 ^T로 바꾸면 바로 저장됩니다.
설정 파일은 아래 경로에 있습니다. 파일이 없으면 기본값으로 실행하며, 자동으로 만들지는 않습니다.
macOS~/Library/Application Support/gluck/config.toml
Linux~/.config/gluck/config.toml
[theme] name = "plain" # plain | catppuccin | tokyo-night | nord | gruvbox | one-light [ui] scroll_lines = 3 # u/d 한 번에 몇 줄 word_wrap = true # w 키로 토글하면 여기에 저장됨 [search] # index_dir = ".glc-index" # 기본: 저장소 루트의 .glc-index/ result_limit = 20 # 모달에 보여줄 결과 수