Skip to content

Commit 903a749

Browse files
committed
feat: show the diff file list
1 parent 3352f3f commit 903a749

20 files changed

+731
-372
lines changed

package.json

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,27 @@
3838
],
3939
"contributes": {
4040
"viewsContainers": {
41-
"panel": [
41+
"activitybar": [
4242
{
4343
"id": "git-panel",
4444
"title": "Git Panel",
45+
"icon": "$(git-commit)"
46+
}
47+
],
48+
"panel": [
49+
{
50+
"id": "git-panel",
51+
"title": "GitPanel",
4552
"icon": "res/icon.png"
4653
}
4754
]
4855
},
4956
"views": {
5057
"git-panel": [
5158
{
59+
"type": "webview",
5260
"id": "git-panel.history",
5361
"name": "Git Panel",
54-
"type": "webview",
5562
"icon": "$(repo-forked)",
5663
"contextualTitle": "History"
5764
},
@@ -65,31 +72,31 @@
6572
},
6673
"commands": [
6774
{
68-
"category": "Git Panel",
75+
"category": "GitPanel",
6976
"command": "git-panel.history",
7077
"title": "History",
7178
"icon": "$(history)"
7279
},
7380
{
74-
"category": "Git Panel",
81+
"category": "GitPanel",
7582
"command": "git-panel.history.filter",
7683
"title": "Git History Filter",
7784
"icon": "$(filter)"
7885
},
7986
{
80-
"category": "Git Panel",
87+
"category": "GitPanel",
8188
"command": "git-panel.history.clear",
8289
"title": "Clear Selection",
8390
"icon": "$(clear-all)"
8491
},
8592
{
86-
"category": "Git Panel",
93+
"category": "GitPanel",
8794
"command": "git-panel.history.refresh",
8895
"title": "Refresh History",
8996
"icon": "$(refresh)"
9097
},
9198
{
92-
"category": "Git Panel",
99+
"category": "GitPanel",
93100
"command": "git-panel.history.switch.branch",
94101
"title": "Select Branch",
95102
"icon": "$(git-branch)"
@@ -121,8 +128,8 @@
121128
}
122129
},
123130
"scripts": {
124-
"build": "vite build && tsup src/index.ts --external vscode",
125-
"dev": "nr build --watch",
131+
"build": "cross-env NODE_ENV=production vite build && tsup src/index.ts --external vscode",
132+
"dev": "concurrently \"vite\" \"cross-env NODE_ENV=development tsup src/index.ts --external vscode --watch\"",
126133
"prepare": "nr update",
127134
"update": "vscode-ext-gen --output src/generated/meta.ts",
128135
"lint": "eslint .",
@@ -147,6 +154,8 @@
147154
"@vue/tsconfig": "^0.7.0",
148155
"bumpp": "^9.5.1",
149156
"concurrently": "^9.1.2",
157+
"cross-env": "^7.0.3",
158+
"dayjs": "^1.11.13",
150159
"eslint": "^9.9.0",
151160
"esno": "^4.7.0",
152161
"pnpm": "^9.7.1",

pnpm-lock.yaml

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/channel/constant.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// webview to vscode channel
2+
export const WEBVIEW_CHANNEL = {
3+
GET_HISTORY: 'get-history',
4+
SHOW_COMMIT_DETAILS: 'show-commit-details',
5+
} as const
6+
7+
// vscode to webview channel
8+
export const CHANNEL = {
9+
HISTORY: 'history',
10+
HISTORY_LOADED: 'history-loaded',
11+
}

src/git/index.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import simpleGit from 'simple-git'
2-
import type { LogResult, SimpleGit } from 'simple-git'
32
import * as vscode from 'vscode'
43

4+
import type { SimpleGit } from 'simple-git'
5+
import type { ExtendedLogResult } from './types'
6+
7+
export * from './types'
8+
59
export class GitService {
6-
private git: SimpleGit
710
private readonly rootRepoPath = vscode.workspace.workspaceFolders![0].uri.fsPath
11+
private _git: SimpleGit
812

913
constructor() {
1014
try {
11-
this.git = simpleGit(this.rootRepoPath, {
15+
this._git = simpleGit(this.rootRepoPath, {
1216
binary: 'git',
1317
maxConcurrentProcesses: 10,
1418
})
@@ -18,9 +22,40 @@ export class GitService {
1822
}
1923
}
2024

21-
async getHistory(): Promise<LogResult> {
25+
get git(): SimpleGit {
26+
return this._git
27+
}
28+
29+
async getHistory(): Promise<ExtendedLogResult> {
2230
try {
23-
return await this.git.log([])
31+
const logResult = await this.git.log(['--max-count=100']) as ExtendedLogResult
32+
33+
// Get stats for each commit
34+
for (const commit of logResult.all) {
35+
try {
36+
const stats = await this.git.raw(['show', '--stat', '--format=', commit.hash])
37+
const lines = stats.trim().split('\n')
38+
const lastLine = lines[lines.length - 1]
39+
40+
if (lastLine && lastLine.includes('changed')) {
41+
const filesMatch = lastLine.match(/(\d+) files? changed/)
42+
const addMatch = lastLine.match(/(\d+) insertions?\(\+\)/)
43+
const delMatch = lastLine.match(/(\d+) deletions?\(-\)/)
44+
45+
commit.stats = {
46+
files: filesMatch ? Number.parseInt(filesMatch[1]) : 0,
47+
additions: addMatch ? Number.parseInt(addMatch[1]) : 0,
48+
deletions: delMatch ? Number.parseInt(delMatch[1]) : 0,
49+
}
50+
}
51+
}
52+
catch (error) {
53+
console.warn(`Failed to get stats for commit ${commit.hash}:`, error)
54+
commit.stats = { files: 0, additions: 0, deletions: 0 }
55+
}
56+
}
57+
58+
return logResult
2459
}
2560
catch (error) {
2661
console.error('Error getting git history:', error)

src/git/types.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { ListLogLine, LogResult } from 'simple-git'
2+
3+
export interface Commit extends ListLogLine {
4+
hash: string
5+
authorName: string
6+
authorEmail: string
7+
message: string
8+
body: string
9+
date: string
10+
stats?: {
11+
files: number
12+
additions: number
13+
deletions: number
14+
}
15+
}
16+
17+
export interface CommitStats {
18+
files: number
19+
additions: number
20+
deletions: number
21+
}
22+
23+
export interface ExtendedLogResult extends LogResult {
24+
all: Array<LogResult['all'][0] & { stats?: CommitStats }>
25+
}

src/index.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
1-
import { defineExtension } from 'reactive-vscode'
21
import * as vscode from 'vscode'
32

43
import { GitPanelViewProvider } from './views/webview'
4+
import { GitChangesProvider } from './views/diff'
5+
import { GitService } from './git'
6+
import { DiffViewService } from './views/diff/DiffViewService'
57

68
import { logger } from './utils'
79

810
export function activate(context: vscode.ExtensionContext) {
911
logger.info('Git Panel Activated')
10-
const provider = new GitPanelViewProvider(vscode.Uri.file(__dirname), context)
12+
13+
const gitService = new GitService()
14+
const diffViewService = DiffViewService.initialize(gitService)
15+
16+
const provider = new GitPanelViewProvider(vscode.Uri.file(__dirname), context, gitService)
1117
vscode.window.registerWebviewViewProvider(GitPanelViewProvider.viewType, provider)
12-
}
1318

14-
export function deactivate() {
15-
// Clean up resources
19+
const gitChangesProvider = new GitChangesProvider()
20+
vscode.window.createTreeView('git-panel.changes', {
21+
treeDataProvider: gitChangesProvider,
22+
showCollapseAll: true,
23+
})
24+
25+
context.subscriptions.push({
26+
dispose: () => {
27+
diffViewService.dispose()
28+
},
29+
})
1630
}

0 commit comments

Comments
 (0)