authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-22 11:08:54 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-04-22 11:08:54 -07:00
log2f002caa03f13fe44701e3bc2d182a0e4f510667
treea7dd8780f9355b469b06e39655e7cd4e208fe5fe
parent9f15225b5d8808504932309d3a257460887c34c4
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

move Tree, Commit, Tag below Repository


1 files changed, 153 insertions(+), 153 deletions(-)

git.zig+153-153
...@@ -242,20 +242,6 @@ fn parseAt(time_part: string, tz_part: string) time.DateTime {...@@ -242,20 +242,6 @@ fn parseAt(time_part: string, tz_part: string) time.DateTime {
242 return at;242 return at;
243}243}
244244
245pub const Commit = struct {
246 tree: TreeId,
247 parents: []const CommitId,
248 author: UserAndAt,
249 committer: UserAndAt,
250 message: string,
251};
252
253pub const UserAndAt = struct {
254 name: string,
255 email: string,
256 at: time.DateTime,
257};
258
259fn parseTreeMode(input: string) !Tree.Object.Mode {245fn parseTreeMode(input: string) !Tree.Object.Mode {
260 const t = tracer.trace(@src(), "", .{});246 const t = tracer.trace(@src(), "", .{});
261 defer t.end();247 defer t.end();
...@@ -269,133 +255,6 @@ fn parseTreeMode(input: string) !Tree.Object.Mode {...@@ -269,133 +255,6 @@ fn parseTreeMode(input: string) !Tree.Object.Mode {
269 };255 };
270}256}
271257
272pub const Tree = struct {
273 children: MultiArrayList(Object),
274
275 pub fn get(self: Tree, name: string) ?Object {
276 if (self.children.len() <= 1000) {
277 for (self.children.items.name, 0..) |a_name, i| {
278 if (std.mem.eql(u8, a_name, name)) {
279 return self.children.get(i);
280 }
281 }
282 return null;
283 }
284 const i = std.sort.binarySearch([]const u8, self.children.items.name, name, extras.compareFnSlice(u8)) orelse return null;
285 return self.children.get(i);
286 }
287
288 pub fn getBlob(self: Tree, name: string) ?Object {
289 const o = self.get(name) orelse return null;
290 if (o.id != .blob) return null;
291 return o;
292 }
293
294 pub fn find(self: Tree, name: string) ?Object {
295 for (self.children.items.name, 0..) |item, i| {
296 if (std.ascii.eqlIgnoreCase(item, name)) {
297 return self.children.get(i);
298 }
299 }
300 return null;
301 }
302
303 pub fn findBlob(self: Tree, name: string) ?Object {
304 const o = self.find(name) orelse return null;
305 if (o.id != .blob) return null;
306 return o;
307 }
308
309 pub const Object = struct {
310 mode: Mode,
311 id: AnyId,
312 name: [:0]const u8,
313
314 pub const Mode = struct {
315 type: Type,
316 perm_user: Perm,
317 perm_group: Perm,
318 perm_other: Perm,
319
320 pub fn format(self: Mode, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void {
321 _ = fmt;
322 _ = options;
323 try writer.print("{}", .{self.type});
324 try writer.print("{}", .{self.perm_user});
325 try writer.print("{}", .{self.perm_group});
326 try writer.print("{}", .{self.perm_other});
327 }
328
329 pub fn nprint(self: Mode, writer: anytype) !void {
330 try self.type.nprint(writer);
331 try self.perm_user.nprint(writer);
332 try self.perm_group.nprint(writer);
333 try self.perm_other.nprint(writer);
334 }
335
336 pub fn eql(self: Mode, other: Mode) bool {
337 if (self.type != other.type) return false;
338 if (self.perm_user != other.perm_user) return false;
339 if (self.perm_group != other.perm_group) return false;
340 if (self.perm_other != other.perm_other) return false;
341 return true;
342 }
343 };
344
345 pub const Type = enum(u8) {
346 file = 100,
347 directory = 40,
348 submodule = 160,
349 symlink = 120,
350 none = 0,
351
352 pub fn format(self: Type, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void {
353 _ = fmt;
354 _ = options;
355 try writer.writeByte(switch (self) {
356 .file => '-',
357 .directory => 'd',
358 .submodule => 'm',
359 .symlink => '-',
360 .none => '-',
361 });
362 }
363
364 pub fn nprint(self: Type, writer: anytype) !void {
365 try writer.writeAll(&.{switch (self) {
366 .file => '-',
367 .directory => 'd',
368 .submodule => 'm',
369 .symlink => '-',
370 .none => '-',
371 }});
372 }
373 };
374
375 pub const Perm = packed struct(u3) {
376 execute: bool,
377 write: bool,
378 read: bool,
379
380 pub fn format(self: Perm, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void {
381 _ = fmt;
382 _ = options;
383 try writer.writeByte(if (self.read) 'r' else '-');
384 try writer.writeByte(if (self.write) 'w' else '-');
385 try writer.writeByte(if (self.execute) 'x' else '-');
386 }
387
388 pub fn nprint(self: Perm, writer: anytype) !void {
389 try writer.writeAll(&.{
390 if (self.read) 'r' else '-',
391 if (self.write) 'w' else '-',
392 if (self.execute) 'x' else '-',
393 });
394 }
395 };
396 };
397};
398
399// TODO make this inspect .git manually258// TODO make this inspect .git manually
400// TODO make this return a Reader when we implement it ourselves259// TODO make this return a Reader when we implement it ourselves
401pub fn getTreeDiff(alloc: std.mem.Allocator, dir: nfs.Dir, commitid: CommitId, parentid: ?CommitId) !string {260pub fn getTreeDiff(alloc: std.mem.Allocator, dir: nfs.Dir, commitid: CommitId, parentid: ?CommitId) !string {
...@@ -685,11 +544,6 @@ pub const TreeDiff = struct {...@@ -685,11 +544,6 @@ pub const TreeDiff = struct {
685 };544 };
686};545};
687546
688pub const Ref = struct {
689 oid: Id,
690 label: string,
691};
692
693pub fn parseTag(tagfile: string) !Tag {547pub fn parseTag(tagfile: string) !Tag {
694 const t = tracer.trace(@src(), "", .{});548 const t = tracer.trace(@src(), "", .{});
695 defer t.end();549 defer t.end();
...@@ -716,13 +570,6 @@ pub fn parseTag(tagfile: string) !Tag {...@@ -716,13 +570,6 @@ pub fn parseTag(tagfile: string) !Tag {
716 return result;570 return result;
717}571}
718572
719pub const Tag = struct {
720 object: Id,
721 type: RefType,
722 tagger: ?UserAndAt,
723 message: string,
724};
725
726// TODO make this inspect .git/objects573// TODO make this inspect .git/objects
727pub fn getBlame(alloc: std.mem.Allocator, dir: nfs.Dir, at: CommitId, sub_path: string) !string {574pub fn getBlame(alloc: std.mem.Allocator, dir: nfs.Dir, at: CommitId, sub_path: string) !string {
728 const t = tracer.trace(@src(), " {s} -- {s}", .{ at.id, sub_path });575 const t = tracer.trace(@src(), " {s} -- {s}", .{ at.id, sub_path });
...@@ -1493,6 +1340,159 @@ fn traverseTo(r: *Repository, arena: std.mem.Allocator, treestart_id: TreeId, di...@@ -1493,6 +1340,159 @@ fn traverseTo(r: *Repository, arena: std.mem.Allocator, treestart_id: TreeId, di
1493 return tree;1340 return tree;
1494}1341}
14951342
1343pub const Tree = struct {
1344 children: MultiArrayList(Object),
1345
1346 pub fn get(self: Tree, name: string) ?Object {
1347 if (self.children.len() <= 1000) {
1348 for (self.children.items.name, 0..) |a_name, i| {
1349 if (std.mem.eql(u8, a_name, name)) {
1350 return self.children.get(i);
1351 }
1352 }
1353 return null;
1354 }
1355 const i = std.sort.binarySearch([]const u8, self.children.items.name, name, extras.compareFnSlice(u8)) orelse return null;
1356 return self.children.get(i);
1357 }
1358
1359 pub fn getBlob(self: Tree, name: string) ?Object {
1360 const o = self.get(name) orelse return null;
1361 if (o.id != .blob) return null;
1362 return o;
1363 }
1364
1365 pub fn find(self: Tree, name: string) ?Object {
1366 for (self.children.items.name, 0..) |item, i| {
1367 if (std.ascii.eqlIgnoreCase(item, name)) {
1368 return self.children.get(i);
1369 }
1370 }
1371 return null;
1372 }
1373
1374 pub fn findBlob(self: Tree, name: string) ?Object {
1375 const o = self.find(name) orelse return null;
1376 if (o.id != .blob) return null;
1377 return o;
1378 }
1379
1380 pub const Object = struct {
1381 mode: Mode,
1382 id: AnyId,
1383 name: [:0]const u8,
1384
1385 pub const Mode = struct {
1386 type: Type,
1387 perm_user: Perm,
1388 perm_group: Perm,
1389 perm_other: Perm,
1390
1391 pub fn format(self: Mode, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void {
1392 _ = fmt;
1393 _ = options;
1394 try writer.print("{}", .{self.type});
1395 try writer.print("{}", .{self.perm_user});
1396 try writer.print("{}", .{self.perm_group});
1397 try writer.print("{}", .{self.perm_other});
1398 }
1399
1400 pub fn nprint(self: Mode, writer: anytype) !void {
1401 try self.type.nprint(writer);
1402 try self.perm_user.nprint(writer);
1403 try self.perm_group.nprint(writer);
1404 try self.perm_other.nprint(writer);
1405 }
1406
1407 pub fn eql(self: Mode, other: Mode) bool {
1408 if (self.type != other.type) return false;
1409 if (self.perm_user != other.perm_user) return false;
1410 if (self.perm_group != other.perm_group) return false;
1411 if (self.perm_other != other.perm_other) return false;
1412 return true;
1413 }
1414 };
1415
1416 pub const Type = enum(u8) {
1417 file = 100,
1418 directory = 40,
1419 submodule = 160,
1420 symlink = 120,
1421 none = 0,
1422
1423 pub fn format(self: Type, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void {
1424 _ = fmt;
1425 _ = options;
1426 try writer.writeByte(switch (self) {
1427 .file => '-',
1428 .directory => 'd',
1429 .submodule => 'm',
1430 .symlink => '-',
1431 .none => '-',
1432 });
1433 }
1434
1435 pub fn nprint(self: Type, writer: anytype) !void {
1436 try writer.writeAll(&.{switch (self) {
1437 .file => '-',
1438 .directory => 'd',
1439 .submodule => 'm',
1440 .symlink => '-',
1441 .none => '-',
1442 }});
1443 }
1444 };
1445
1446 pub const Perm = packed struct(u3) {
1447 execute: bool,
1448 write: bool,
1449 read: bool,
1450
1451 pub fn format(self: Perm, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void {
1452 _ = fmt;
1453 _ = options;
1454 try writer.writeByte(if (self.read) 'r' else '-');
1455 try writer.writeByte(if (self.write) 'w' else '-');
1456 try writer.writeByte(if (self.execute) 'x' else '-');
1457 }
1458
1459 pub fn nprint(self: Perm, writer: anytype) !void {
1460 try writer.writeAll(&.{
1461 if (self.read) 'r' else '-',
1462 if (self.write) 'w' else '-',
1463 if (self.execute) 'x' else '-',
1464 });
1465 }
1466 };
1467 };
1468};
1469
1470pub const Commit = struct {
1471 tree: TreeId,
1472 parents: []const CommitId,
1473 author: UserAndAt,
1474 committer: UserAndAt,
1475 message: string,
1476};
1477
1478pub const UserAndAt = struct {
1479 name: string,
1480 email: string,
1481 at: time.DateTime,
1482};
1483
1484pub const Tag = struct {
1485 object: Id,
1486 type: RefType,
1487 tagger: ?UserAndAt,
1488 message: string,
1489};
1490
1491pub const Ref = struct {
1492 oid: Id,
1493 label: string,
1494};
1495
1496/// Variant on std.MultiArrayList but using an allocation per-field rather than a single for the entire structure.1496/// Variant on std.MultiArrayList but using an allocation per-field rather than a single for the entire structure.
1497fn MultiArrayList(T: type) type {1497fn MultiArrayList(T: type) type {
1498 return struct {1498 return struct {