1use grit_lib::index::MODE_TREE;
6use grit_lib::objects::{parse_tree, serialize_commit, CommitData, ObjectKind};
7use grit_lib::refs;
8use grit_lib::repo::init_repository;
9use grit_lib::rev_parse::resolve_revision;
10use grit_lib::write_tree::write_tree_from_index;
11
12fn walk_tree(
13 repo: &grit_lib::repo::Repository,
14 tree_oid: grit_lib::objects::ObjectId,
15 prefix: &str,
16) -> grit_lib::error::Result<()> {
17 let obj = repo.odb.read(&tree_oid)?;
18 let entries = parse_tree(&obj.data)?;
19 for e in entries {
20 let name = String::from_utf8_lossy(&e.name);
21 let path = if prefix.is_empty() {
22 name.into_owned()
23 } else {
24 format!("{prefix}/{name}")
25 };
26 if e.mode == MODE_TREE {
27 println!("{path}/ (tree {})", e.oid);
28 walk_tree(repo, e.oid, &path)?;
29 } else {
30 println!("{path} -> {}", e.oid);
31 }
32 }
33 Ok(())
34}
35
36fn main() -> grit_lib::error::Result<()> {
37 let root = tempfile::tempdir()?;
38 let repo = init_repository(root.path(), false, "main", None, "files")?;
39
40 use grit_lib::index::{Index, IndexEntry, MODE_REGULAR};
41
42 let blob_a = repo.odb.write(ObjectKind::Blob, b"a\n")?;
43 let blob_b = repo.odb.write(ObjectKind::Blob, b"b\n")?;
44
45 let mut index = Index::new();
46 for (rel, oid) in [
47 (b"a.txt".as_slice(), blob_a),
48 (b"sub/b.txt".as_slice(), blob_b),
49 ] {
50 let entry = IndexEntry {
51 ctime_sec: 0,
52 ctime_nsec: 0,
53 mtime_sec: 0,
54 mtime_nsec: 0,
55 dev: 0,
56 ino: 0,
57 mode: MODE_REGULAR,
58 uid: 0,
59 gid: 0,
60 size: 0,
61 oid,
62 flags: (rel.len().min(0xfff)) as u16,
63 flags_extended: None,
64 path: rel.to_vec(),
65 base_index_pos: 0,
66 };
67 index.add_or_replace(entry);
68 }
69 repo.write_index(&mut index)?;
70 let index = repo.load_index()?;
71 let tree_oid = write_tree_from_index(&repo.odb, &index, "")?;
72
73 let commit = CommitData {
74 tree: tree_oid,
75 parents: Vec::new(),
76 author: "Example <example@example.com> 1700000000 +0000".to_owned(),
77 committer: "Example <example@example.com> 1700000000 +0000".to_owned(),
78 author_raw: Vec::new(),
79 committer_raw: Vec::new(),
80 encoding: None,
81 message: "tree walk\n".to_owned(),
82 raw_message: None,
83 };
84 let commit_oid = repo
85 .odb
86 .write(ObjectKind::Commit, &serialize_commit(&commit))?;
87 refs::write_ref(&repo.git_dir, "refs/heads/main", &commit_oid)?;
88
89 let head_commit = resolve_revision(&repo, "HEAD")?;
90 let commit_obj = repo.odb.read(&head_commit)?;
91 let parsed = grit_lib::objects::parse_commit(&commit_obj.data)?;
92 println!("walking tree at {}", parsed.tree);
93 walk_tree(&repo, parsed.tree, "")?;
94
95 Ok(())
96}