Skip to content

Commit 772db3d

Browse files
committed
feat: It just refreshes automatically after the operation is completed
1 parent f6d1da2 commit 772db3d

File tree

4 files changed

+115
-5
lines changed

4 files changed

+115
-5
lines changed

src/commands/diff.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ export default function diffCommand(gitService: GitService, diffProvider: DiffPr
2020
// For modified files, show diff between current commit and its parent
2121
if (fileInfo.status === 'M') {
2222
try {
23-
const parentCommit = await gitService.getParentCommit(commit)
24-
if (parentCommit) {
25-
const leftUri = GitService.toGitUri(uri, parentCommit)
23+
const previousCommit = await gitService.getPreviousCommit(commit)
24+
if (previousCommit) {
25+
const leftUri = GitService.toGitUri(uri, previousCommit)
2626
const rightUri = GitService.toGitUri(uri, commit)
2727
await vscode.commands.executeCommand('vscode.diff', leftUri, rightUri, title)
2828
return

src/git/GitChangeMonitor.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import * as vscode from 'vscode'
2+
3+
export class GitChangeMonitor {
4+
private disposables: vscode.Disposable[] = []
5+
private fileWatcher: vscode.FileSystemWatcher | undefined
6+
private retryCount = 0
7+
8+
constructor(private readonly onGitChange: () => void) {
9+
this.initialize()
10+
this.setupFileSystemWatcher()
11+
}
12+
13+
private setupFileSystemWatcher() {
14+
try {
15+
this.fileWatcher = vscode.workspace.createFileSystemWatcher('**/.git/index')
16+
17+
this.disposables.push(
18+
this.fileWatcher.onDidChange(() => {
19+
this.onGitChange()
20+
}),
21+
this.fileWatcher.onDidCreate(() => {
22+
this.onGitChange()
23+
}),
24+
this.fileWatcher.onDidDelete(() => {
25+
this.onGitChange()
26+
}),
27+
)
28+
}
29+
catch (error) {
30+
console.error('Error setting up file watcher:', error)
31+
}
32+
}
33+
34+
async getGitExtension() {
35+
try {
36+
const extension = vscode.extensions.getExtension(
37+
'vscode.git',
38+
)
39+
40+
if (extension !== undefined) {
41+
const gitExtension = extension.isActive
42+
? extension.exports
43+
: await extension.activate()
44+
45+
const api = gitExtension.getAPI(1)
46+
return api
47+
}
48+
}
49+
catch (err) {
50+
console.error('Error getting git extension:', err)
51+
throw new Error(`Git extension not found: ${err}`)
52+
}
53+
54+
return undefined
55+
}
56+
57+
private async initialize() {
58+
try {
59+
const git = await this.getGitExtension()
60+
61+
if (!git && this.retryCount === 0) {
62+
console.error('Failed to get Git extension API, will retry after 5 seconds...')
63+
setTimeout(() => this.initialize(), 5000)
64+
return
65+
}
66+
67+
if (!git.repositories || git.repositories.length === 0) {
68+
this.disposables.push(git.onDidOpenRepository((repo: any) => {
69+
this.setupRepository(repo)
70+
}))
71+
}
72+
else {
73+
git.repositories.forEach((repo: any) => this.setupRepository(repo))
74+
}
75+
}
76+
catch (error) {
77+
console.error('Error in initialize:', error)
78+
// 如果出错,5秒后重试
79+
setTimeout(() => this.initialize(), 5000)
80+
}
81+
}
82+
83+
private setupRepository(repo: any) {
84+
try {
85+
this.disposables.push(repo.state.onDidChange(() => {
86+
this.onGitChange()
87+
}))
88+
}
89+
catch (error) {
90+
console.error('Error setting up repository:', error)
91+
}
92+
}
93+
94+
dispose() {
95+
this.disposables.forEach(d => d.dispose())
96+
this.disposables = []
97+
if (this.fileWatcher) {
98+
this.fileWatcher.dispose()
99+
this.fileWatcher = undefined
100+
}
101+
}
102+
}

src/git/index.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import type { ExtendedLogResult } from './types'
77
export * from './types'
88

99
export class GitService {
10-
private readonly rootRepoPath = vscode.workspace.workspaceFolders![0].uri.fsPath
10+
private readonly rootRepoPath: string
1111
private _git: SimpleGit
1212

1313
constructor() {
14+
if (!vscode.workspace.workspaceFolders || vscode.workspace.workspaceFolders.length === 0)
15+
throw new Error('No workspace folder found. Please open a folder first.')
16+
17+
this.rootRepoPath = vscode.workspace.workspaceFolders[0].uri.fsPath
18+
1419
try {
1520
this._git = simpleGit(this.rootRepoPath, {
1621
binary: 'git',
@@ -63,7 +68,7 @@ export class GitService {
6368
}
6469
}
6570

66-
async getParentCommit(commitHash: string): Promise<string | null> {
71+
async getPreviousCommit(commitHash: string): Promise<string | null> {
6772
try {
6873
const result = await this.git.raw(['rev-list', '--parents', '-n', '1', commitHash])
6974
const [, parentHash] = result.trim().split(' ')

src/views/webview.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Uri, commands } from 'vscode'
44
import { DiffProvider } from './diff/DiffProvider'
55

66
import type { GitService } from '@/git'
7+
import { GitChangeMonitor } from '@/git/GitChangeMonitor'
78
import { StorageService } from '@/storage'
89
import { CHANNEL, WEBVIEW_CHANNEL } from '@/constant'
910

@@ -13,6 +14,7 @@ export class GitPanelViewProvider implements vscode.WebviewViewProvider {
1314
private gitService: GitService
1415
private storageService: StorageService
1516
private gitChangesProvider: DiffProvider
17+
private _gitChangeMonitor: GitChangeMonitor
1618
public static readonly viewType = 'git-panel.history'
1719
private _commits: Commit[] = []
1820
private _view?: vscode.WebviewView
@@ -24,6 +26,7 @@ export class GitPanelViewProvider implements vscode.WebviewViewProvider {
2426
this.gitService = gitService
2527
this.storageService = StorageService.getInstance()
2628
this.gitChangesProvider = DiffProvider.getInstance()
29+
this._gitChangeMonitor = new GitChangeMonitor(() => this.refreshHistory(true))
2730
this._commits = this.storageService.getCommits()
2831
}
2932

0 commit comments

Comments
 (0)