-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathcli.ts
92 lines (75 loc) · 2.23 KB
/
cli.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
/**
* Git CLI module.
*
* Run Git CLI commands within the extension and capture the text output.
*/
import util = require("util");
import childProcess = require("child_process");
import { getWorkspaceFolder } from "../workspace";
const exec = util.promisify(childProcess.exec);
/**
* Run a `git` subcommand with options and return output.
*/
export function execute(
cwd: string,
subcommand: string,
options: string[] = []
) {
const command = `git ${subcommand} ${options.join(" ")}`;
const result = exec(command, { cwd });
return result;
}
/**
* Run `git diff-index` with given flags and return output.
*
* This will return both staged and unstaged changes. Pass '--cached' to use staged changes only.
* Always excludes untracked files.
*
* Empty lines will be dropped - because of no changes or just the way the command-line data comes
* in or got split.
*
* The output already seems to never have color info, from my testing, but the no-color flagged is
* added still to be safe.
*/
async function _diffIndex(options: string[] = []): Promise<Array<string>> {
const cmd = "diff-index";
const fullOptions = [
"--name-status",
"--find-renames",
"--find-copies",
"--no-color",
...options,
"HEAD",
];
const workspace = getWorkspaceFolder();
const { stdout, stderr } = await execute(workspace, cmd, fullOptions);
if (stderr) {
console.debug(`stderr for 'git ${cmd}' command:`, stderr);
}
const lines = stdout.split("\n");
return lines.filter(line => line !== "");
}
/**
* List files changed and how they changed.
*
* Look for diff description of staged files, otherwise fall back to all files.
* Always excludes untracked files - make sure to stage a file so it becomes tracked, especially
* in the case of a rename.
*
* Returns an array of strings.
*/
export async function getChanges() {
const stagedChanges = await _diffIndex(["--cached"]);
if (stagedChanges.length) {
console.debug("Found staged changes");
return stagedChanges;
}
console.debug(
"Staging area is empty. Using unstaged files (tracked files only still)."
);
const allChanges = await _diffIndex();
if (!allChanges.length) {
console.debug("No changes found");
}
return allChanges;
}