feat: untracked and modified files are identified by git
Git service offers untracked files and modified ones staged or not filtering out any other statuses and marking if new or modified. This includes renamed files.
This commit is contained in:
parent
d6e9cec04d
commit
9c1d1cb557
1 changed files with 99 additions and 0 deletions
99
src/git.zig
99
src/git.zig
|
|
@ -174,6 +174,105 @@ pub fn status(context_: usize) Error!void {
|
||||||
}.result, exit_null(tag));
|
}.result, exit_null(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_or_modified_files(context_: usize) Error!void {
|
||||||
|
const tag = @src().fn_name;
|
||||||
|
try git_err(context_, .{
|
||||||
|
"--no-optional-locks",
|
||||||
|
"status",
|
||||||
|
"--porcelain=v2",
|
||||||
|
"--null",
|
||||||
|
}, struct {
|
||||||
|
fn result(context: usize, parent: tp.pid_ref, output: []const u8) void {
|
||||||
|
var it_ = std.mem.splitScalar(u8, output, 0);
|
||||||
|
var counter: u8 = 0;
|
||||||
|
|
||||||
|
while (it_.next()) |line| {
|
||||||
|
var it = std.mem.splitScalar(u8, line, ' ');
|
||||||
|
const rec_type = if (it.next()) |type_tag|
|
||||||
|
std.meta.stringToEnum(StatusRecordType, type_tag) orelse {
|
||||||
|
if (type_tag.len > 0)
|
||||||
|
std.log.debug("found {s}, it happens when a file is renamed and not modified. Check `git --no-optional-locks status --porcelain=v2`", .{type_tag});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
switch (rec_type) {
|
||||||
|
.@"1" => { // ordinary file: <XY> <sub> <mH> <mI> <mW> <hH> <hI> <path>
|
||||||
|
const sub = it.next() orelse return;
|
||||||
|
const mH = it.next() orelse return;
|
||||||
|
var vcs_status: u8 = undefined;
|
||||||
|
if (sub[0] == 'A') {
|
||||||
|
// New staged file is shown as new
|
||||||
|
vcs_status = '+';
|
||||||
|
} else if (sub[0] == 'M' or sub[1] == 'M') {
|
||||||
|
if (mH[0] == 'S') {
|
||||||
|
// We do not handle submodules, yet
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vcs_status = '~';
|
||||||
|
} else {
|
||||||
|
// We will not edit deleted files
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0..5) |_| {
|
||||||
|
_ = it.next() orelse return;
|
||||||
|
}
|
||||||
|
var path: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer path.deinit(allocator);
|
||||||
|
while (it.next()) |path_part| {
|
||||||
|
if (path.items.len > 0) path.append(allocator, ' ') catch return;
|
||||||
|
path.appendSlice(allocator, path_part) catch return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.send(.{ module_name, context, tag, vcs_status, path.items }) catch {};
|
||||||
|
counter += 1;
|
||||||
|
},
|
||||||
|
.@"2" => {
|
||||||
|
const sub = it.next() orelse return;
|
||||||
|
if (sub[0] != 'R') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// An staged file is editable
|
||||||
|
// renamed: <XY> <sub> <mH> <mI> <mW> <hH> <hI> <rn> <path>
|
||||||
|
for (0..7) |_| {
|
||||||
|
_ = it.next() orelse return;
|
||||||
|
}
|
||||||
|
var path: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer path.deinit(allocator);
|
||||||
|
while (it.next()) |path_part| {
|
||||||
|
if (path.items.len > 0) path.append(allocator, ' ') catch return;
|
||||||
|
path.appendSlice(allocator, path_part) catch return;
|
||||||
|
}
|
||||||
|
parent.send(.{ module_name, context, tag, '+', path.items }) catch {};
|
||||||
|
counter += 1;
|
||||||
|
},
|
||||||
|
.@"?" => { // untracked file: <path>
|
||||||
|
var path: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer path.deinit(allocator);
|
||||||
|
while (it.next()) |path_part| {
|
||||||
|
if (path.items.len > 0) path.append(allocator, ' ') catch return;
|
||||||
|
path.appendSlice(allocator, path_part) catch return;
|
||||||
|
}
|
||||||
|
parent.send(.{ module_name, context, tag, '+', path.items }) catch {};
|
||||||
|
counter += 1;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
// Omit showing other statuses
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std.log.info("git: {} changed files", .{counter});
|
||||||
|
}
|
||||||
|
}.result, struct {
|
||||||
|
fn result(_: usize, _: tp.pid_ref, output: []const u8) void {
|
||||||
|
var it = std.mem.splitScalar(u8, output, '\n');
|
||||||
|
while (it.next()) |line| if (line.len > 0)
|
||||||
|
std.log.err("{s}: {s}", .{ module_name, line });
|
||||||
|
}
|
||||||
|
}.result, exit_null(tag));
|
||||||
|
}
|
||||||
|
|
||||||
fn git_line_output(context_: usize, comptime tag: []const u8, cmd: anytype) Error!void {
|
fn git_line_output(context_: usize, comptime tag: []const u8, cmd: anytype) Error!void {
|
||||||
try git_err(context_, cmd, struct {
|
try git_err(context_, cmd, struct {
|
||||||
fn result(context: usize, parent: tp.pid_ref, output: []const u8) void {
|
fn result(context: usize, parent: tp.pid_ref, output: []const u8) void {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue