WFU

[ 精選文章 ]

自行車 入門 Escape 3 , Snap 21 , Revel

最近周末想運動 , 平日想通勤 , 想買台自行車 , 把自己找的資料跟大家分享 , 如果你是玩家級的 就不用看了 這是給跟我一樣的新新新手 參考的 騎車半年後的補充: 如果你有把握你是真的有時間有興趣會一直騎,建議還是存點錢買好一點的彎把公路車, 或是可以考慮買2手的自...

2026年5月3日 星期日

VS Search Extension

VSsearch Extension : VSsearch 0.2

Vss-GUI : 下載  Vss-Cli : 下載




先開好 Bios Git 以 Cathaya 為例 先 reset Head 到之前的 07A Release 的點
用 VS code 打開Folder 選定資料夾 Z(須為Git 資料夾)
選擇手動使用 VSIX 安裝延伸套件




建議選擇之前的版本為主版本 (用可能會需要DBG的最早的版本為優)

會自動判別 Release xxxxNNA 為主要版本
這邊選擇的是07A 做增量差異 到 08A 08B 09A 都還算快
07A 第一次做 index DB 在我的電腦 大概需要 7 分鐘 (i9-13900F / 64GB Ram)
大概在 42.6% 左右會等一uv84

右下角會顯示進度 ETA 是剩多久
但由於中間有大量跳過的檔案 也有大型文字檔
所以並不準確
一般大概就是 7-10分鐘 左右

4x% 附近會卡一下 要有耐心



多次嘗試  大概都是七分多左右會好 (以Cathaya 專案為例 不同專案當然不同結果)


Search 快速鍵 Ctrl-Alt-F
Search 標記的文字 Ctrl-Alt-S
檢索速度基本上小於 1 秒

Vss-GUI 有更多的完整 DB 功能可以處理更多狀況
Vss-Cli 可以嫁接一般的 IDE 工具


01 / overview

專案簡介

VSsearch 是一個專為大型 Git 倉庫(特別是 UEFI / BIOS / 韌體專案)設計的 離線全文搜尋引擎。它將每個倉庫索引成三個獨立的 SQLite 檔案 —— meta.db(路徑與雜湊)、text.db(FTS5 trigram 文字倒排索引)、 bin.db(FTS5 over hex,選配)—— 並在內容讀取之前就透過 副檔名路由、內容嗅探、中段 Shannon 熵值三層閘門決定該檔走 text、bin、both 還是跳過。

設計目標是讓一台沒有伺服器、沒有網路的開發機, 在不到一秒內跨越上萬個檔案查到任意關鍵字,同時仍能跟上 Git 的分支與 commit 變動。

毫秒級查詢
FTS5 Trigram 倒排索引,典型查詢 200~900 ms(29k 檔 / 1.4 GB 文字 DB)。
📦
三檔分離架構
meta + text + bin 各自獨立;可單獨重建 text 而不動 bin,可只下載 meta+text 做純文字查詢。
🧭
智慧路由
副檔名白名單 → 內容嗅探 → 預設路由;可用 --as-text / --as-binary 強制覆寫。
🎯
熵值過濾器
針對 1 MB 以上檔案讀取中段樣本,計算 Shannon 熵值;> 7.2 bits/byte 視為壓縮/加密內容跳過。
🔁
Git-aware 增量
Main + Minor 分層;Minor 只記分支差異,查詢時合併。
🛠
Git 路徑可設定
CLI --git > 環境變數 VSS_GIT > vss.config.json > PortableGit 預設 > PATH。
02 / tech choices

技術選擇與設計理由

每個關鍵設計決策背後都有具體理由。以下是 VSsearch 的選擇及被淘汰的替代方案。

1. SQLite FTS5 + Trigram tokenizer

選項評估
SQLite FTS5 + trigram ← 採用單檔、零伺服器、Python 內建、trigram 模式下任意子字串查詢都可走倒排索引。WAL 模式讓並行讀寫不衝突。
Elasticsearch / OpenSearch需 JVM、記憶體佔用 1–2 GB、需維運 cluster。每個倉庫額外起一個伺服器不現實。
Whoosh / TantivyWhoosh 寫入慢;Tantivy 需 Rust toolchain,Python binding 非原生,且不內建 trigram。
Lucene (PyLucene)需 JVM,安裝複雜;查詢快但部署門檻過高。
直接用 ripgrep每次查詢都掃整個 disk。30k 檔 / 2 GB 純文字一般要 5–8 秒,無法快取。
為何是 trigram 而非詞彙 tokenizer?原始碼裡的符號常是 EFI_STATUSgBS->LocateProtocol 這種包含底線、箭頭、大小寫混雜的形式。詞彙 tokenizer 會把它們切成 EFI+STATUS,導致查不到原串。Trigram(3 字元滑動窗)能讓任意長度 ≥ 3 的子字串都走索引。

2. 三檔分離 (meta / text / bin)

  • 關注點分離:不同資料的生命週期不同。meta 幾乎不變;text 隨原始碼變;bin 只在 firmware 重新編譯時變。分開可以只重建需要的那個。
  • 按需部署:只要文字查詢?只需釋出 meta + text,二進位備份可獨立排除。
  • 並行寫入:FTS5 trigram 寫入成本高。拆成兩個不同 DB 並行寫入避免 BUSY 鎖定。
  • ATTACH 重組:SQLite 原生支援 ATTACH DATABASE,查詢時能把 Main + Minor 的三檔同時掛起來走 SQL UNION,不需手動合併。

3. 中段 Shannon 熵值過濾

選項評估
Mid-sample Shannon (1–3 KiB) ← chosen微量讀取(1 次 seek + 1 KiB read)就能辨別壓縮/加密/韌體 blob。原始碼熵值 < 5,壓縮接近 8.0,門檻 7.2 安全切割。
只看副檔名適用一般專案,但 EDK2 裡許多 .bin 是小 ASCII 表;.dat 也雙面性。單靠副檔名會誤判。
全檔讀取統計準確但慢。50 MB 全讀需 200–500 ms。中段抽樣誤判率 < 0.5%,但快 50×。
首 8 KiB 嗅探頭部會說謊。許多 firmware blob 前 4 KiB 是結構化 header;中段抽樣才看到真正 payload。

4. Git blob SHA 作為變更訊號

  • 零讀檔 skip:git 已為每個追蹤檔案算了 SHA-1 (或 SHA-256)。git ls-tree 一句搞定。與上次 SHA 一致則內容未變、可跳過所有讀取與雜湊。
  • 比 mtime 可靠:mtime 在 git checkoutgit stash pop、雲端同步後都會變,但內容用 SHA 識別才是準的。mtime 僅作為 SHA 不可用時的 fallback。
  • 比 BLAKE2b 快:BLAKE2b 7–8 GB/s 已經很快,但仍需讀全檔;SHA-skip 是「根本不讀」。零 IO 永遠贏快 IO。

5. ThreadPoolExecutor + 單一 writer thread

  • SQLite 寫入是序列化的。多個 connection 同時寫入會 BUSY。並行讀檔 + 序列寫入是唯一能同時遮掩 IO 並避免鎖競爭的架構。
  • 為什麼不用 multiprocessing?Python GIL 在 IO 與 SQLite C-extension 中都會釋放,讀檔 + decode + hash 實際上能並行。multiprocessing 反而要 pickle 每個 byte buffer,會是淨退步。

6. PyInstaller --onefile 單 EXE 部署

  • 現場零依賴:封閉網路、公司 build server 不一定有 Python。單 EXE 是唯一能 copy 即用的形式。
  • git 不被打包是有意為之:git 自身是個生態(credential helper / hooks / submodule),固定一份反而脆弱。預設偵測 PortableGit + 5 級覆寫更穩健。
03 / benefits

優點與限制

主要優點

  • 零伺服器、零網路:查詢 100% 本機;企業防火牆內可用。
  • 狀態可攜帶.vssearch/ 可隨 ZIP 帶走、可被 patch。
  • Git-aware 增量:SHA-skip 讓「重建」在無變動時為數秒達成。
  • Trigram 子字串:詞彙 tokenizer 查不到的 EFI_->Pcd__attribute__ 都能命中。
  • 能查 binary:HEX 模式能在韌體 image 裡查 byte sequence。
  • 分支差異儲存:Minor 只記 diff;100 個分支不會 100× 儲存。
  • 可設定的 git 路徑:5 層解析適合多 git 安裝環境(PortableGit / Cygwin / msys)。

已知限制

  • 不是即時 watcher:變更要跑 vss-build minor 才進索引。可用 git hooks 自動化,但不是 inotify。
  • 查詢長度 < 3 無法走 trigram:FTS5 trigram 最小單位 3 字元。「if」「At」這類查詢退為慢的 LIKE 掃描。
  • FTS5 文字索引體積大:~2 GB 原始碼產 ~1.4 GB 的 text.db,約原始碼 70%。
  • 需要 git:SHA-skip 與分支意識依賴 git。非 Git 倉庫需手動 main 快照模式。
  • 僅 Windows EXE:本倉隱含 PyInstaller 設定為 Windows;Linux/macOS 用戶請直接跑 Python 原始碼。
04 / comparison

工具比較

在 ~30k 檔 / ~2 GB 原始碼倉庫上,每個工具的實際型態:

工具建立成本查詢時間適合場景不適合場景
VSsearch~390 s 首次
< 5 s 增量
200–900 ms重複查詢同倉庫、跨分支、binary HEX只查一次的場景
ripgrep (rg)05–8 s一次性、未知倉庫、regex緊密查詢、binary、無分支概念
git grep02–6 s指定 commit 查詢跨 commit、binary、不能跨倉庫
VS Code 全文搜尋0 (背景 ripgrep)5–10 s編輯時隨手查含二進位的 firmware repo 會凍死、不能腳本化
ctags / cscope1–3 min< 50 ms定義 / 引用跳轉只能查符號,不能查任意子串、跨 commit 弱
Elasticsearch / OpenSearch1–3 hr 含部署50–150 ms多人共用、多倉庫、需 ranking個人機、離線、企業防火牆
Sourcegraph需 Docker / k8s50–200 ms多倉庫、code intelligence離線個人機、無企業部署
Hound (etsy)~5 min100–300 ms多倉庫 regex無分支、無 binary、無增量
Zoekt~10 min< 100 ms多倉庫 trigram、高 QPS使用門檻高、無 binary、需 Go runtime
i
選擇原則一次性查詢 → ripgrep;重複查同一倉庫 + 跨分支或查二進位 → VSsearch;多人共用 web UI → Sourcegraph。
05 / architecture

系統架構

三層架構:CLI 介面層 → 核心引擎層(vss/) → SQLite 儲存層(三檔分離)。

── system layers ──
INTERFACE LAYERcli/vss_build.py → vss-build.execli/vss_search.py → vss-search.exeCORE ENGINE — vss/indexer.pybuild_main / minorrouting.pytext / bin / both / skipentropy.pymid-sample Shannongitinfo.pyCatFileBatch / shadb.pyschema / ATTACHsearch.pyFTS5 / fuzzy / globextract.pydecode / hex emitconfig.py / hooks.pyJSON / git hooksSQLITE STORAGE — <repo>/.vssearch/*_meta.db*_text.db (FTS5)*_bin.db (HEX)
06 / modules

模組職責

模組職責
vss/indexer.py主建立流程:列舉 → 分發 → 處理 → 寫入。包含 build_main / build_minor / build_minor_for_ref 與 BuildStats
vss/routing.py決定每個檔案要走 text、bin、both 還是 skip。包含 RoutingConfigRouter、預設副檔名表。
vss/entropy.py中段樣本 + Shannon 熵值;用於識別韌體 blob 或壓縮檔。
vss/gitinfo.pygit wrapper:head_shals_tree_atdiff_name_onlyCatFileBatch。可設定 git 執行檔路徑。
vss/db.pySQLite schema、ATTACH 配置、FTS5 trigram 虛擬表、checkpoint。
vss/search.py查詢入口:8 種模式、後置篩選器、Main+Minor 合併。
vss/extract.py解碼文字內容、產生 HEX 字串。
vss/config.pyJSON 設定載入;定義 Config 與預設值。
vss/hooks.pygit hook 安裝(post-checkout / post-merge 自動重建 Minor)。
cli/vss_build.py建立 CLI:main / minor / clean / chain / promote / install-hooks
cli/vss_search.py查詢 CLI:模式、篩選、JSON 輸出。
07 / algorithm

索引演算法

建立流程分為四個階段:列舉、預過濾、處理、寫入。多個 worker 並行讀檔與雜湊,單一 writer thread 序列化寫入 SQLite,避免鎖競爭。

列舉 Enumerategit ls-tree(main)或 git diff(minor)取得檔案清單與 blob SHA。
SHA 比對 SHA-skip與既有 meta 比對 blob SHA;未變則直接累加 skipped_unchanged,零次讀檔。
路由決策 Routing手動覆寫 → 副檔名白名單 → 8 KiB 內容嗅探 → 預設 text。
熵值過濾 Entropy filter若檔案 > 1 MB 且路由非 skip,讀取中段樣本;> 7.2 bits/byte 或檔案 > max_index_mb 即跳過。
解碼 / HEX Decoding / hextext 路由 → 嘗試 UTF-8/UTF-16/Latin-1 解碼;bin 路由 → 產生空白分隔的 HEX 字串。
寫入 Write200 筆/批,writer thread 寫入 meta + text-FTS5 + bin-FTS5;最後 WAL checkpoint。
08 / routing

檔案路由

每個檔案會被路由到下列四種目的之一:

Route含義儲存
text純文字內容*_text.db (FTS5)
bin二進位 / HEX 索引*_bin.db (FTS5 over hex)
both同時索引文字與 HEX兩邊
skip完全不索引

Decision order

  1. 手動 glob 覆寫:--as-text / --as-binary
  2. 副檔名白名單:text_exts / binary_exts / both_exts
  3. 內容嗅探:讀取首 8 KiB;含 NUL 或 < 85% 文字位元組則視為 binary
  4. 預設:text
EDK2 預設.fd / .fv / .efi / .rom / .bin 直接走 bin 路由;--no-bin 進一步把 bin 路由改成 skip,得到「只有文字」的 DB。
09 / entropy

熵值過濾器

對 1 MB 以上檔案,從中段抽樣計算 Shannon 熵值;高熵內容(壓縮 / 加密 / 韌體 blob)通常 > 7.95,原始碼 < 5。預設門檻 7.2。

檔案大小樣本大小
≤ 1 MB不檢查(首 8 KiB 嗅探已夠)
1 MB < size ≤ 10 MB1024 bytes
10 MB < size ≤ 20 MB2048 bytes
> 20 MB3072 bytes

Skip reasons

  • size:NMB — 檔案大小超過 max_index_mb(預設 50)
  • entropy:X.XX — 中段熵值高於門檻
  • mid-binary — 中段樣本含 NUL byte(二進位)
  • routed:skip — 路由決定跳過(如 --no-bin 下的二進位副檔名)
10 / tiered

分層索引

使用 Main + Minor 兩層架構:Main 是完整 release 快照,Minor 只儲存與 Main 的差異。查詢時兩者合併,Minor 優先。

files# <repo>/.vssearch/
main_manual_af0ec2c_af0ec2c_meta.db    # paths, hashes, route
main_manual_af0ec2c_af0ec2c_text.db    # FTS5 trigram (text)
main_manual_af0ec2c_af0ec2c_bin.db     # FTS5 over hex (omitted with --no-bin)

minor_dev_7dcdc85_meta.db                 # delta vs MainDB (current branch)
minor_dev_7dcdc85_text.db
minor_dev_7dcdc85_bin.db

查詢時 search 模組將 Main 與當前分支的 Minor 透過 ATTACH DATABASE 同時開啟,在 SQL 層做 UNION 與 dedup(Minor 優先)。

11 / flowchart

建立流程

── build pipeline ──
vss-build maingit ls-tree HEAD{path → blob_sha}for each fileSHA == prev?(zero-read skip)yesskipped_unchangednoroute?routing.pyskipskipped_routedtext/bin/bothsize > 1MB?entropy > 7.2 ?yesskipped_entropy/sizenodecode + INSERT (writer thread)meta.db + text.db + bin.db (batches of 200)
13 / usage

基本用法

CLI 結構vss-build <subcommand> [options]  /  vss-search QUERY [options]

vss-build subcommands

cmd用途
main建立完整 MainDB(指定 release commit)
minor為當前分支建立 MinorDB(與 Main 的差異)
chain為所有本地分支建立 MinorDB
promote把 MinorDB 合併進新的 MainDB 快照
clean刪除舊的 MinorDB(保留最近 N 個)
install-hooks安裝 git hook 自動重建 MinorDB

vss-search modes

--mode說明
exact完全比對(預設)
prefix前綴比對 foo*
substr子字串(trigram 加速)
fuzzy編輯距離模糊比對
fuzzysub子字串 + 模糊
globSQL GLOB 萬用字元
hexHEX byte 序列(查 bin DB)
ext列出特定副檔名的檔案
14 / parameters

參數列表

vss-build

flag類型說明
--repopath倉庫根目錄(預設:cwd)
--releasestrmain 用,指定 release commit SHA 或 ref
--configpathvss.config.json
--db-dirpathDB 輸出目錄(覆寫 config)
--workersintworker 執行緒數(0 = auto)
--no-binflag不建立 bin DB
--ext-text .Xlist追加 text 路由副檔名
--ext-binary .Xlist追加 binary 路由副檔名
--as-text GLOBlist強制 glob 走 text
--as-binary GLOBlist強制 glob 走 binary
--max-index-mb Nint硬性大小上限(預設 50;0 取消)
--entropy-threshold Xfloat熵值門檻(預設 7.2)
--no-entropy-checkflag關閉熵值/中段過濾
--list-skippedflag列印所有跳過的檔案路徑
--profile NAMEstr套用副檔名 profile(如 c, py)
--git PATHstr覆寫 git 執行檔路徑
--quietflag關閉進度輸出

vss-search

flag類型說明
QUERYstr搜尋字串(--mode ext 可省略)
--modeenumexact / prefix / substr / fuzzy / fuzzysub / glob / hex / ext
--ext .c .hlist副檔名篩選
--path GLOBstr路徑 glob 篩選
--exclude GLOBstr排除 glob
--limit Nint最多回傳筆數(預設 500)
--max-dist 0~3intfuzzy 最大編輯距離
--case-sensitiveflag區分大小寫
--branch NAMEstr指定分支(覆寫當前分支)
--jsonflag輸出 JSON
--git PATHstr覆寫 git 執行檔路徑
15 / examples

使用範例

建立 MainDB(純文字)

PowerShell$REPO = "e:\Git\Cathaya\Cathaya_GC"
$BUILD = "e:\Git\repository\VSsearchExtension\dist\vss-build.exe"
$H     = (& 'E:\Git\PortableGit\bin\git.exe' -C $REPO rev-parse HEAD).Trim()

& $BUILD main --repo $REPO --release $H --no-bin --list-skipped

建立完整索引(text + bin)

cmdvss-build.exe main --repo e:\Git\Cathaya\Cathaya_GC --release 7dcdc854b

分支 MinorDB

PowerShell& $BUILD minor --repo $REPO
& $BUILD chain --repo $REPO     # every local branch

查詢(多種模式)

PowerShell$SEARCH = "e:\Git\repository\VSsearchExtension\dist\vss-search.exe"

# Exact (default)
& $SEARCH EFI_STATUS --repo $REPO --limit 5

# Substring
& $SEARCH "gBS->LocateProtocol" --mode substr --repo $REPO

# Fuzzy with edit distance 1, restrict to .c / .h
& $SEARCH "PcdMximumLinkedListLength" --mode fuzzy --max-dist 1 --ext .c .h --repo $REPO

# HEX byte sequence (queries bin DB)
& $SEARCH "55 AA" --mode hex --repo $REPO

# Glob
& $SEARCH "Init*Pcd*" --mode glob --repo $REPO

# Path filter + exclude
& $SEARCH EFI_STATUS --path "AmiNetworkPkg/**" --exclude "**/test/**" --repo $REPO

# Tighter entropy / smaller cap
& $BUILD main --repo $REPO --release $H --max-index-mb 20 --entropy-threshold 6.5

真實效能

指標數值(Cathaya_GC)
total_seen29,567
indexed29,075
routed-skip (binary ext)492
entropy / size / mid-binary skips0 (--no-bin already filters)
wall time (text only)~390 s (Python) / ~530 s (EXE)
text.db size1,365 MB
meta.db size8.4 MB
EFI_STATUS substr350 ms (py) / 905 ms (exe)
PcdMaximumLinkedListLength substr215 ms (py) / 710 ms (exe)
16 / config

設定檔

vss.config.json 放在倉庫根目錄;可選。

vss.config.json{
  "db_dir": ".vssearch",
  "workers": 0,
  "git_executable": "E:\\Git\\PortableGit\\bin\\git.exe",
  "release_regex": "^release\\s+\\w{5}(?:\\d{2}[AB]|\\d{3})$",
  "branch_pins": { "dev": "main" },
  "routing": {
    "text_exts":    [".c", ".h", ".inf", ".dec", ".dsc"],
    "binary_exts":  [".fd", ".fv", ".efi"],
    "max_index_mb": 50,
    "entropy_threshold": 7.2,
    "entropy_check_enabled": true
  },
  "extension_profiles": {
    "c":  [".c", ".h", ".cpp", ".hpp"],
    "py": [".py", ".pyi"]
  }
}

git path resolution order

  1. --git PATH CLI 旗標
  2. VSS_GIT 環境變數
  3. vss.config.json:git_executable
  4. E:\Git\PortableGit\bin\git.exe (若存在)
  5. git (PATH 查找)
16b / vs code extension

VS Code 擴充套件

vscode-extension/ 將 VSsearch 整合進 VS Code 側邊面板,提供搜尋表單、結果樹、資料庫管理檢視,並支援切換分支時自動建立 MinorDB。 擴充套件本身用 TypeScript 撰寫,後端則透過 JSON-RPC over stdio 與一個 長駐的 Python sidecarvss-server.exe)溝通。

元件職責
extension.ts啟用、命令註冊、Webview / Tree 註冊
server.tsspawn sidecar、JSON-RPC client、pending-id Map、自動重啟
searchProvider.ts查詢分派 + 結果快取
resultsTree.tsTreeDataProvider(File→Hit 或扁平)
indexer.tsbuild/clean/delete + DB 列表
gitWatcher.ts監看 .git/HEAD、debounced 自動建 MinorDB
cli/vss_server.pyJSON-RPC 主迴圈、進度通知
16c / json-rpc

JSON-RPC 長駐伺服器

每個工作區資料夾啟動一個 vss-server.exe 子行程,透過 stdin/stdout 傳輸 line-delimited JSON-RPC。一筆請求 {"id":N,"method":"search","params":{...}},回應 {"id":N,"result":...};長時間操作(buildMain / buildMinor)以 {"id":N,"progress":{...}} 推送進度。

為何採用「長駐」而非「一次一進程」

成本一次一進程長駐 sidecar
EXE 解壓 (PyInstaller --onefile)~400 ms / call啟動一次
Python interpreter 啟動~150 ms / call一次
SQLite open + FTS5 mmap~80 ms / call保持開啟
git cat-file 子行程每次重啟--batch 常駐
查詢快取 (LRU)命中重複查詢

實測:第二次查詢同一字串可從 ~700 ms 降至 <30 ms。切換分支後的增量重建因為 git cat-file 已就緒,省下每檔 ~10 ms 的 fork 成本,在 29k 檔倉庫累積為數百毫秒。

RPC 方法總覽

method說明
init設定 repo 路徑、回傳 git 資訊
search主要查詢(mode / ext / max_hits …)
build_main / build_minor建立索引(含 progress)
list_dbs列出 main / minor / branch 各層
delete_tier / clean_minors / clear_cache維護操作
git_info驗證 git 可用
shutdown乾淨關閉
16d / flow

演算法流程

  1. 啟動:擴充套件 activate → 找到工作區根目錄 → spawn vss-server.exe → 等待 {"id":0,"ready":true}
  2. 初始化:呼叫 init,sidecar 載入 vss.ini、解析 PortableGit、開啟現有 DBs。
  3. 查詢:使用者按 Ctrl+Alt+F → webview 送 search → searchProvider 合併預設選項 → sidecar FTS5 查詢 → 串流回 hits → resultsTree 建立 File→Hit 樹。
  4. 跳轉:點擊 hit → vscode.open 打開檔案至指定行;或在 Search Editor 模式下,使用 VS Code 內建 search-result 語法做原生點擊。
  5. 分支切換FileSystemWatcher 偵測 .git/HEAD 變動 → debounce 300 ms → 靜默呼叫 build_minor → 進度只寫到 OutputChannel,不打擾使用者。
  6. 關閉:deactivate → 送 shutdown → 等 sidecar 結束 → 若 5 秒未結束則 kill。
16e / file structure

檔案結構

擴充套件原始碼

treeVSsearchExtension/
├─ cli/
│  ├─ vss_build.py        # build CLI
│  ├─ vss_search.py       # search CLI
│  ├─ vss_gui.py          # Tk GUI front-end
│  └─ vss_server.py       # JSON-RPC sidecar (NEW)
├─ vss/                   # core engine package
├─ vscode-extension/
│  ├─ src/
│  │  ├─ extension.ts     # activate, commands, webviews
│  │  ├─ server.ts        # spawn sidecar, JSON-RPC client
│  │  ├─ searchProvider.ts
│  │  ├─ resultsTree.ts
│  │  ├─ searchEditor.ts
│  │  ├─ indexer.ts
│  │  ├─ gitWatcher.ts
│  │  ├─ config.ts
│  │  └─ types.ts
│  ├─ bin/
│  │  └─ vss-server.exe   # bundled by _packExt.bat
│  ├─ out/                # tsc output (generated)
│  ├─ package.json        # manifest, commands, settings
│  ├─ tsconfig.json
│  ├─ INSTALL.md          # EN install guide
│  ├─ INSTALL_tw.md       # 中文安裝指南
│  └─ README.md
├─ dist/
│  ├─ vss-build.exe
│  ├─ vss-search.exe
│  ├─ vss-server.exe
│  └─ vssearch-0.2.0.vsix # final extension package
├─ _pack.bat              # PyInstaller build (CLIs + sidecar)
└─ _packExt.bat           # copy EXE + tsc + vsce package

資料庫位置(重要)

i
所有索引一律存放在repo 內的 <repo-root>\.vssearch\,不可改放他處。每個工作區資料夾擁有獨立的 sidecar 與獨立的 .vssearch
tree<repo-root>/.vssearch/
├─ main/      # full-history tier per release commit
├─ minor/     # incremental tiers on top of main
├─ branch/    # per-branch tiers (auto-built on branch switch)
└─ cache/     # transient query cache

記得加進 .gitignore

.gitignore/.vssearch/
16f / install

安裝說明

需求

  • VS Code ≥ 1.85.0
  • Git(PATH 或 vss.ini 中的 PortableGit 路徑)
  • Windows x64(內建 sidecar 為 EXE;Linux/macOS 改用 vssearch.pythonPath

安裝預先建置的 .vsix

pwshcode --install-extension dist\vssearch-0.2.0.vsix

從原始碼建置

pwshcd e:\Git\repository\VSsearchExtension
_pack.bat       # dist\vss-build.exe / vss-search.exe / vss-server.exe
_packExt.bat    # copy EXE -> bin\, tsc -p ., vsce package -> dist\vssearch-*.vsix

首次使用

  1. 開啟一個 Git 工作目錄
  2. 點擊活動列的 VSsearch 圖示(Search / Results / Databases 三檢視)
  3. 執行 VSsearch: Build Main DB(必要的一次性步驟)
  4. 按 Ctrl+Alt+F 搜尋

命令一覽(v0.2.0)

命令用途
VSsearch: Search開啟搜尋面板(Ctrl+Alt+F
VSsearch: Search Selection以編輯器選取文字搜尋(Ctrl+Alt+S
VSsearch: Build Main / Minor DB建立完整或增量索引
VSsearch: Clean Old Minors...保留最新 N 個 minor,清除其餘
VSsearch: Delete Tier刪除單一層級(在 Databases 視圖右鍵)
VSsearch: Refresh Databases重新列出 Databases 視圖
VSsearch: Open Last Result in Editor以 Search Editor 顯示最近一次結果
VSsearch: Clear Query Cache清除 sidecar 的查詢快取
VSsearch: Show Git Info將 branch / HEAD / git 路徑印至 Output
VSsearch: Reveal Database Folder在系統檔案總管開啟 <repo>\.vssearch\
VSsearch: Export Last Results...將目前結果匯出為 .json / .csv
VSsearch: Dump Diagnostics開啟 JSON 文件,含版本、設定、DB 列表
VSsearch: Reset First-Run Prompt重新啟用首次「立即建置?」提示
VSsearch: Restart Server重新啟動 Python sidecar
VSsearch: Wipe Local Index (.vssearch)停止 sidecar、刪除 <repo>\.vssearch\、重新啟動
VSsearch: Uninstall (Wipe Index + Remove Extension)清除索引並執行 uninstallExtension kvh.vssearch

常見問題

症狀解法
"git executable not found"設定 VSS_GIT 或在 vss.ini 設 PortableGit;詳見下方「Git 找不到」食譜
結果為空且無錯誤先執行 Build Main DB
sidecar 持續重啟看 Output → VSsearch 的 stderr
分支切換後結果過時執行 Build Minor DB 或等待 watcher
想完全清除索引刪除 <repo>\.vssearch\

「Git 找不到」食譜

sidecar 每次建索引 / 搜尋都會呼叫 git。解析順序(先中先贏):

  1. VS Code 設定 vssearch.gitExecutable
  2. 環境變數 $VSS_GIT
  3. vss.ini → [git] executable (硬覆寫)
  4. vss.ini → [git] portable_default (僅當檔案存在時採用)
  5. git  PATH

A. 針對單一工作區 — VS Code 設定(最簡單)

.vscode/settings.json{
  "vssearch.gitExecutable": "E:\\Git\\PortableGit\\bin\\git.exe"
}

然後執行 VSsearch: Restart Server.

B. 機器全域 — 在 sidecar 旁邊放 vss.ini

內建 sidecar 位於 %USERPROFILE%\.vscode\extensions\kvh.vssearch-<ver>\bin\,在同一資料夾內新增 vss.ini

vss.ini[git]
executable = E:\Git\PortableGit\bin\git.exe
; or: only used as fallback when 'executable' is empty AND the file exists
portable_default = E:\Git\PortableGit\bin\git.exe

C. 使用者層環境變數

pwsh[Environment]::SetEnvironmentVariable('VSS_GIT', 'E:\Git\PortableGit\bin\git.exe', 'User')

關閉並重新開啟 VS Code,讓它重新繼承環境。

D. 將 Git 加入 PATH

PortableGit 在 <PortableGit>\bin\ 與 <PortableGit>\cmd\ 下都有 git.exe,任選一個加入 PATH 後重新開啟 VS Code。

i
驗證
  • VSsearch: Restart Server
  • VSsearch: Show Git Info — 提示顯示 branch / HEAD;Output 頻道記錄 git_exe
  • VSsearch: Dump Diagnostics — JSON 內含 gitInfo.git_exe 與 settings.gitExecutable

解除安裝

最簡單的做法是內建命令:Ctrl+Shift+P → VSsearch: Uninstall (Wipe Index + Remove Extension)。它會停止 sidecar、刪除目前工作區的 <repo>\.vssearch\,再執行 workbench.extensions.uninstallExtension kvh.vssearch

若只想清除索引但保留擴充套件,請改用 VSsearch: Wipe Local Index (.vssearch)

pwsh# Manual / scripted uninstall
code --list-extensions | Select-String vssearch
code --uninstall-extension kvh.vssearch                   # 0.2.0+
code --uninstall-extension undefined_publisher.vssearch   # legacy 0.1.x
# Optional: per indexed repo
Remove-Item -Recurse -Force <repo>\.vssearch
i
VSsearch 不會在 <repo>\.vssearch\ 之外寫入任何資料,僅有一個工作區 globalState 旗標 (vssearch.firstRunHandled),VS Code 在移除擴充套件時會自動清除。

完整文件: INSTALL.md / INSTALL_tw.md

17 / packaging

EXE 封裝

使用 PyInstaller --onefile 模式封裝為單一 EXE,需要 pyinstallerpip install pyinstaller)。

cmdcd e:\Git\repository\VSsearchExtension
_pack.bat
REM Output:
REM   dist\vss-build.exe   (~12 MB)
REM   dist\vss-search.exe  (~12 MB)

_pack.bat 會:

  1. 對每個 CLI 呼叫 ..\_gen_version_info.py 產生 version_info.txt
  2. 執行 PyInstaller,使用 ..\Rewolf.ico 圖示與 --collect-submodules vss
!
git 不會被封裝進 EXE執行 EXE 的機器仍需有 git(透過 PATH 或上述解析順序找到)。預設會自動偵測 E:\Git\PortableGit\bin\git.exe
18 / performance

效能

情境時間說明
29k 檔 / 純文字 / Python 直接呼叫390 s
29k 檔 / 純文字 / EXE530 s--onefile 解壓開銷
純文字查詢(trigram)200~900 ms取決於匹配數
SHA-skip 增量重建< 5 s無變更檔案
19 / summary

總結

VSsearch 的每個選擇都是「被使用者現場的限制」逆向推導出來的: SHA-first 增量 避免冗餘讀取、 Trigram 倒排 讓任意子字串走索引、 三檔分離 讓不同生命週期的資料可獨立重建、 中段熵值過濾 避免韌體 blob 污染文字索引、 並行讀 + 序列寫 讓 SQLite 完全不碰 BUSY。 它不是要取代 ripgrep 或 Elasticsearch,而是填補「個人開發者每天反覆查同一個大倉庫」這個被忽視的中間地帶。

建議下一步
  • 把 vss.config.json 放進 repo 設定 git_executable 與 routing 預設。
  • 執行 vss-build install-hooks 讓分支切換時自動重建 MinorDB。
  • 大型分支用 chain 一次跑完所有分支。