forked from changesets/ghcommit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit.ts
More file actions
113 lines (107 loc) · 2.83 KB
/
Copy pathgit.ts
File metadata and controls
113 lines (107 loc) · 2.83 KB
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
111
112
113
import { promises as fs } from "fs";
import git from "isomorphic-git";
import { commitFilesFromBuffers } from "./node";
import {
CommitChangesFromRepoArgs,
CommitFilesFromBuffersArgs,
CommitFilesResult,
} from "./interface";
/**
* @see https://isomorphic-git.org/docs/en/walk#walkerentry-mode
*/
const FILE_MODES = {
directory: 0o40000,
file: 0o100644,
executableFile: 0o100755,
symlink: 0o120000,
} as const;
export const commitChangesFromRepo = async ({
base,
repoDirectory = process.cwd(),
log,
...otherArgs
}: CommitChangesFromRepoArgs): Promise<CommitFilesResult> => {
const ref = base?.commit ?? "HEAD";
const gitLog = await git.log({
fs,
dir: repoDirectory,
ref,
depth: 1,
});
const oid = gitLog[0]?.oid;
if (!oid) {
throw new Error(`Could not determine oid for ${ref}`);
}
// Determine changed files
const trees = [git.TREE({ ref: oid }), git.WORKDIR()];
const additions: CommitFilesFromBuffersArgs["fileChanges"]["additions"] = [];
const deletions: CommitFilesFromBuffersArgs["fileChanges"]["deletions"] = [];
const fileChanges = {
additions,
deletions,
};
await git.walk({
fs,
dir: repoDirectory,
trees,
map: async (filepath, [commit, workdir]) => {
// Don't include ignored files
if (
await git.isIgnored({
fs,
dir: repoDirectory,
filepath,
})
) {
return null;
}
if (
(await commit?.mode()) === FILE_MODES.symlink ||
(await workdir?.mode()) === FILE_MODES.symlink
) {
throw new Error(
`Unexpected symlink at ${filepath}, GitHub API only supports files and directories. You may need to add this file to .gitignore`,
);
}
const prevOid = await commit?.oid();
const currentOid = await workdir?.oid();
// Don't include files that haven't changed, and exist in both trees
if (prevOid === currentOid && !commit === !workdir) {
return null;
}
// Iterate through anything that may be a directory in either the
// current commit or the working directory
if (
(await commit?.type()) === "tree" ||
(await workdir?.type()) === "tree"
) {
// Iterate through these directories
return true;
}
if (!workdir) {
// File was deleted
deletions.push(filepath);
return null;
} else {
// File was added / updated
const arr = await workdir.content();
if (!arr) {
throw new Error(`Could not determine content of file ${filepath}`);
}
additions.push({
path: filepath,
contents: Buffer.from(arr),
});
}
return true;
},
});
return commitFilesFromBuffers({
...otherArgs,
fileChanges,
log,
base: {
commit: oid,
},
});
};