forked from joshdick/git-fuzzy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit-fuzzy
executable file
·111 lines (84 loc) · 3.46 KB
/
git-fuzzy
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
#!/usr/bin/env node
var spawn = require("child_process").spawn,
path = require("path"),
fuzzy = require("fuzzy");
var handleError = function(exitCode) {
if (exitCode !== 0) {
console.error("fatal: git-fuzzy execution error.");
process.exit(exitCode);
}
};
//Runs a command as a child process.
//If a callback is supplied, it will be invoked with the
//child process's stdout once the child process terminates.
//If no callback is supplied, the child process will use our
//process's stderr/stdout (preserving colors, if applicable.)
var run = function(command, arguments, callback) {
var spawnOptions = callback ? {} : { stdio: "inherit" },
ps = spawn(command, arguments, spawnOptions);
if (callback) {
var stderr = "",
stdout = "";
ps.stdout.on("data", function(data) {
stdout += data;
});
ps.stderr.on("data", function(data) {
stderr += data;
});
ps.on("close", function(exitCode) {
if (exitCode !== 0) {
if (stderr) {
process.stderr.write(stderr);
}
handleError(exitCode);
} else {
callback(stdout.trim());
}
});
} else {
ps.on("close", handleError);
}
};
if (process.argv.length < 3) {
console.error("usage: git fuzzy <command> [<args>]");
console.error("git-fuzzy will assume the last argument should fuzzy-match a filename that appears in the output of \"git status\".");
process.exit(1);
}
var git_args = process.argv.slice(2, -1),
last_arg = process.argv.slice(-1).toString();
//If a standalone Git command was specified, or if the last argument looks like a Git argument rather than a filename, just fall through to Git.
if (process.argv.length === 3 || last_arg.charAt(0) === "-") {
run("git", process.argv.slice(2));
//Otherwise, assume the last argument is a fuzzy filename.
} else {
run("git", ["status", "--porcelain"], function(status) {
var git_status_lines = status.trim().split(/\n/);
if (git_status_lines.length === 0) {
console.error("fatal: nothing to match against; git-fuzzy only works when the working directory isn't clean.");
process.exit(1);
}
var haystack = []; //A list of strings to fuzzy match against
for (var i = 0; i < git_status_lines.length; i++) {
var line = git_status_lines[i].trim();
line = line.substring(2).trim(); //Strip the leading status flag and separator
var tokens = line.split(" -> "); //Split by arrow in case something got renamed, but wrap in an array in all cases
haystack = haystack.concat(tokens);
}
var matches = fuzzy.filter(last_arg, haystack).map(function(el) { return el.string; });
if (matches.length === 0) {
console.error("fatal: no matches");
process.exit(1);
} else if (matches.length > 1) {
console.error("fatal: more than one match; please be more specific");
console.error("matches:");
for (var j = 0; j < matches.length; j++) {
console.error("\t" + matches[j]);
}
process.exit(1);
} else {
run("git", ["rev-parse", "--show-toplevel"], function(git_root) {
run("git", [].concat(git_args, path.join(git_root, matches[0])));
});
}
});
}