-
Notifications
You must be signed in to change notification settings - Fork 0
/
statusMatrix.mjs
80 lines (74 loc) · 2.36 KB
/
statusMatrix.mjs
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
import { STAGE, TREE, WORKDIR, walk, isIgnored } from 'isomorphic-git'
export function statusMatrix({
fs,
dir,
gitdir = dir + '/.git',
ref = 'HEAD',
filepaths = ['.'],
filter = (filepath) => true,
cache = {},
}) {
return walk({
fs,
cache,
dir,
gitdir,
trees: [TREE({ ref }), WORKDIR(), STAGE()],
map: async function(filepath, [head, workdir, stage]) {
// Ignore ignored files, but only if they are not already tracked.
if (!head && !stage && workdir) {
if (
await isIgnored({
fs,
dir,
filepath,
})
) {
return null
}
}
// match against base paths
if (!filepaths.some(base => worthWalking(filepath, base))) {
return null
}
// Late filter against file names
if (filter) {
if (!filter(filepath)) return
}
// For now, just bail on directories
const headType = head && (await head.type())
if (headType === 'tree' || headType === 'special') return
if (headType === 'commit') return null
const workdirType = workdir && (await workdir.type())
if (workdirType === 'tree' || workdirType === 'special') return
const stageType = stage && (await stage.type())
if (stageType === 'commit') return null
if (stageType === 'tree' || stageType === 'special') return
// Figure out the oids, using the staged oid for the working dir oid if the stats match.
const headOid = head ? await head.oid() : undefined
const stageOid = stage ? await stage.oid() : undefined
let workdirOid
if (!head && workdir && !stage) {
// We don't actually NEED the sha. Any sha will do
// TODO: update this logic to handle N trees instead of just 3.
workdirOid = '42'
} else if (workdir) {
workdirOid = await workdir.oid()
}
const entry = [undefined, headOid, workdirOid, stageOid]
const result = entry.map(value => entry.indexOf(value))
result.shift() // remove leading undefined entry
return [filepath, ...result]
},
})
}
const worthWalking = (filepath, root) => {
if (filepath === '.' || root == null || root.length === 0 || root === '.') {
return true
}
if (root.length >= filepath.length) {
return root.startsWith(filepath)
} else {
return filepath.startsWith(root)
}
}