Skip to content

Commit 5bb5300

Browse files
authored
Merge pull request #122 from itmisx/fix/windows-session-case
🐛 fix: windows session case
2 parents b2fc409 + 998d14e commit 5bb5300

2 files changed

Lines changed: 59 additions & 3 deletions

File tree

session/session.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"io"
2222
"os"
2323
"path/filepath"
24+
"runtime"
2425
"sort"
2526
"strings"
2627
"time"
@@ -126,14 +127,23 @@ func New(workspace string) (*Manager, error) {
126127
if err != nil {
127128
return nil, fmt.Errorf("abs path: %w", err)
128129
}
129-
h := sha1.Sum([]byte(abs))
130-
sid := hex.EncodeToString(h[:])[:16]
131-
132130
home, err := os.UserHomeDir()
133131
if err != nil {
134132
return nil, fmt.Errorf("user home: %w", err)
135133
}
134+
sid := sessionIDFor(abs)
136135
root := filepath.Join(home, ".deepx", "sessions", sid)
136+
137+
// 迁移(issue #121):旧版本直接用原始大小写哈希。Windows 路径大小写不敏感,归一为小写后
138+
// sid 会变,老用户的历史目录(原始大小写哈希)就对不上、看似"丢了"。若新目录还没有、但本次
139+
// 启动大小写对应的旧目录存在,改名过去保住历史。Linux 大小写敏感,rawSid==sid,此段不触发。
140+
if rawSid := rawSessionID(abs); rawSid != sid {
141+
oldRoot := filepath.Join(home, ".deepx", "sessions", rawSid)
142+
if !dirExists(root) && dirExists(oldRoot) {
143+
_ = os.Rename(oldRoot, root) // 失败不致命:退化为新建空 session
144+
}
145+
}
146+
137147
if err := os.MkdirAll(root, 0o755); err != nil {
138148
return nil, fmt.Errorf("mkdir session: %w", err)
139149
}
@@ -145,6 +155,21 @@ func New(workspace string) (*Manager, error) {
145155
return m, nil
146156
}
147157

158+
// sessionIDFor 由 workspace 绝对路径算 session id。Windows 路径大小写不敏感,归一为小写再哈希,
159+
// 避免 `C:\` 与 `c:\` 被算成两个 session(issue #121);Linux 大小写敏感,保持原样,绝不合并不同路径。
160+
func sessionIDFor(abs string) string {
161+
if runtime.GOOS == "windows" {
162+
return rawSessionID(strings.ToLower(abs))
163+
}
164+
return rawSessionID(abs)
165+
}
166+
167+
// rawSessionID 直接对给定字符串做 sha1 取前 16 hex(旧行为)。迁移时用它按原始大小写定位老目录。
168+
func rawSessionID(s string) string {
169+
h := sha1.Sum([]byte(s))
170+
return hex.EncodeToString(h[:])[:16]
171+
}
172+
148173
// SessionID 返回 16 字符 hex,用作目录名与诊断显示。
149174
func (m *Manager) SessionID() string { return m.sessionID }
150175

session/session_id_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package session
2+
3+
import (
4+
"runtime"
5+
"testing"
6+
)
7+
8+
// 核心正确性:Windows 路径大小写不敏感→归一;其它平台大小写敏感→保持区分(防 issue #121 的反向回归)。
9+
func TestSessionIDFor_CaseHandling(t *testing.T) {
10+
a := sessionIDFor(`C:\GitLab\webapi`)
11+
b := sessionIDFor(`c:\gitlab\webapi`)
12+
if runtime.GOOS == "windows" {
13+
if a != b {
14+
t.Fatalf("Windows 应大小写无关,却 %q != %q", a, b)
15+
}
16+
} else {
17+
if a == b {
18+
t.Fatal("非 Windows(大小写敏感)不应归一,否则会把不同路径合并成一个 session")
19+
}
20+
}
21+
}
22+
23+
// 迁移靠 rawSessionID 按【原始大小写】定位旧目录,所以它必须保持大小写敏感、且 16 hex。
24+
func TestRawSessionID(t *testing.T) {
25+
if rawSessionID("/X") == rawSessionID("/x") {
26+
t.Fatal("raw 必须大小写敏感")
27+
}
28+
if got := len(rawSessionID("/x")); got != 16 {
29+
t.Fatalf("应 16 hex, got %d", got)
30+
}
31+
}

0 commit comments

Comments
 (0)