-
Notifications
You must be signed in to change notification settings - Fork 26
/
getProjectGitStatus.ts
110 lines (98 loc) · 2.73 KB
/
getProjectGitStatus.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import fs from "fs"
import * as git from "isomorphic-git"
import {
GitFileStatus,
GitRepositoryStatus,
GitStatusString
} from "../../types"
import { getGitHistory } from "./getGitHistory"
import { getGitStatus } from "./getGitStatus"
import { getGitTrackingStatus } from "./getGitTrackingStatus"
export async function getProjectGitStatus(
projectRoot: string
): Promise<GitRepositoryStatus> {
// branching
const currentBranch = await git.currentBranch({ fs, dir: projectRoot })
const branches = await git.listBranches({ fs, dir: projectRoot })
const history = await getGitHistory(projectRoot, { ref: currentBranch })
// staging
const trackingStatus = await getGitTrackingStatus(projectRoot)
const { tracked, untracked } = trackingStatus
const {
staged,
unstaged,
unmodified,
rawStatusList
} = await getFileStatusInProject(projectRoot, tracked)
return {
rawStatusList,
unstaged,
staged,
currentBranch,
branches,
tracked,
untracked,
unmodified,
history
}
}
export async function getFileStatusInProject(
projectRoot: string,
tracked: string[]
) {
const rawStatusList: GitFileStatus[] = await Promise.all(
tracked.map(async relpath => {
const status = await getGitStatus(projectRoot, relpath)
return { relpath, status, staged: isStaged(status) }
})
)
const { staged, unstaged, unmodified } = getStagingStatus(rawStatusList)
return {
rawStatusList,
staged,
unstaged,
unmodified
}
}
export async function updateFileStatusInProject(
projectRoot: string,
repositoryStatus: GitRepositoryStatus,
relpath: string
): Promise<GitRepositoryStatus> {
const newChange = {
relpath,
staged: false,
status: await getGitStatus(projectRoot, relpath)
}
const rawStatusList = [...repositoryStatus.rawStatusList]
const changedIndex = rawStatusList.findIndex(c => c.relpath === relpath)
if (changedIndex > -1) {
// update status
rawStatusList[changedIndex] = newChange
}
const { staged, unstaged, unmodified } = getStagingStatus(rawStatusList)
return {
...repositoryStatus,
// untracked,
rawStatusList,
staged,
unmodified,
unstaged
}
}
function isStaged(status: GitStatusString | "error"): boolean {
const firstChar = status[0]
return firstChar !== "*"
}
function getStagingStatus(
statusList: GitFileStatus[]
): { staged: string[]; unstaged: string[]; unmodified: string[] } {
const staged = statusList
.filter(a => a.staged && a.status !== "unmodified")
.map(a => a.relpath)
const unmodified = statusList
.filter(a => a.status === "unmodified")
.map(a => a.relpath)
const unstaged = statusList.filter(a => !a.staged).map(a => a.relpath)
return { staged, unstaged, unmodified }
}