From b50bb792b77d7743f2c3861ac2c85b215b77fdc6 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Sat, 25 Jul 2026 23:46:25 +0800
Subject: [PATCH] feat: 实现缓存管理

---
 internal/index/cache.go      |   48 ++++++++++++++++++++++++
 internal/index/cache_test.go |   35 +++++++++++++++++
 2 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/internal/index/cache.go b/internal/index/cache.go
new file mode 100644
index 0000000..b54860c
--- /dev/null
+++ b/internal/index/cache.go
@@ -0,0 +1,48 @@
+package index
+
+import (
+	"os/exec"
+	"strings"
+)
+
+// GetGitCommit 获取知识库当前 git commit hash
+func GetGitCommit(vaultPath string) (string, error) {
+	cmd := exec.Command("git", "-C", vaultPath, "rev-parse", "HEAD")
+	out, err := cmd.Output()
+	if err != nil {
+		return "", err // 不是 git 仓库
+	}
+	return strings.TrimSpace(string(out)), nil
+}
+
+// NeedsRebuild 检查是否需要重建索引
+func NeedsRebuild(store *Store, vaultPath string) (bool, string, error) {
+	currentCommit, err := GetGitCommit(vaultPath)
+	if err != nil {
+		// 不是 git 仓库,总是需要重建
+		return true, "", nil
+	}
+
+	storedCommit, err := store.GetMeta("git_commit")
+	if err != nil {
+		return true, currentCommit, nil
+	}
+
+	if storedCommit == "" {
+		// 没有记录,需要重建
+		return true, currentCommit, nil
+	}
+
+	if storedCommit != currentCommit {
+		// commit 变了,需要重建
+		return true, currentCommit, nil
+	}
+
+	// 检查是否有节点
+	count, _ := store.NodeCount()
+	if count == 0 {
+		return true, currentCommit, nil
+	}
+
+	return false, currentCommit, nil
+}
diff --git a/internal/index/cache_test.go b/internal/index/cache_test.go
new file mode 100644
index 0000000..d686b14
--- /dev/null
+++ b/internal/index/cache_test.go
@@ -0,0 +1,35 @@
+package index
+
+import (
+	"os"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
+
+func TestGetGitCommit(t *testing.T) {
+	// 创建临时 git 仓库
+	tmpDir := t.TempDir()
+	exec.Command("git", "-C", tmpDir, "init").Run()
+	exec.Command("git", "-C", tmpDir, "config", "user.email", "test@test.com").Run()
+	exec.Command("git", "-C", tmpDir, "config", "user.name", "test").Run()
+	os.WriteFile(filepath.Join(tmpDir, "test.md"), []byte("test"), 0644)
+	exec.Command("git", "-C", tmpDir, "add", ".").Run()
+	exec.Command("git", "-C", tmpDir, "commit", "-m", "init").Run()
+
+	commit, err := GetGitCommit(tmpDir)
+	if err != nil {
+		t.Fatalf("GetGitCommit failed: %v", err)
+	}
+	if len(commit) != 40 {
+		t.Errorf("commit length = %d, want 40", len(commit))
+	}
+}
+
+func TestGetGitCommitNotGit(t *testing.T) {
+	tmpDir := t.TempDir()
+	_, err := GetGitCommit(tmpDir)
+	if err == nil {
+		t.Error("expected error for non-git directory")
+	}
+}

--
Gitblit v1.9.1