Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lore-proto/proto/lore/thin_client/v1/model.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ enum NodeType {
LINK = 2;
}

// File mode for a file-system entry.
enum FileMode {
// No special file mode.
NONE = 0;
// File is executable.
EXECUTABLE = 1;
}

// Per-path action describing what happened between two states (or relative
// to the common ancestor in 3-way merges).
enum Action {
Expand Down Expand Up @@ -90,6 +98,10 @@ message TreeNode {
NodeType node_type = 2;
// Content address for FILE / LINK entries; unused for DIRECTORY.
lore.model.v1.Address address = 3;
// Original size in bytes. For DIRECTORY entries, this is the cumulative size of its descendant files.
uint64 size = 4;
// File mode for this entry. For possible flags and values, see enum FileMode.
uint64 mode = 5;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not making this of type FileMode directly because it needs to be able to represent multiple mode flags, so it has to be an integer. Also making it uint64 despite mode internally being u16 for future-proofness and because Protobuf varint encoding takes care of making this small on the wire (0 bytes if mode = NONE and 1 byte if mode = EXECUTABLE).

}

// Self-describing revision record. Carries the resolved RevisionIdentifier
Expand Down
6 changes: 6 additions & 0 deletions lore-proto/src/grpc/lore.thin_client.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ pub struct TreeNode {
/// Content address for FILE / LINK entries; unused for DIRECTORY.
#[prost(message, optional, tag = "3")]
pub address: ::core::option::Option<crate::lore::model::v1::Address>,
/// Original size in bytes. For DIRECTORY entries, this is the cumulative size of its descendant files.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if size for DIRECTORY entries being the sum of all descendant files is a guarantee that Lore fundamentally provides or whether it just happens to be like that in the current implementation. If it's not something Lore wants to commit to, we could explicitly set this to 0 for directories.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is definitely something Lore provides - with the caveat that it is the full unfiltered size of all child nodes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be possible to math-it-out, like, subtract the sizes of child directory nodes, to get the size of files in the directory?

@jblazquez jblazquez Jun 19, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the current behavior is actually better. Imagine a UI that shows the contents of the repo as a tree view. At each level, it could show a size next to a directory that describes the total size of everything under that directory, recursively, so you can at a glance see where the largest parts of the repo are.

@ahaczewski ahaczewski Jun 20, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I think that it can do both: show the size of files in the directory and the tree beneath. Just make two fields, makes the API reacher

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lore usually avoids duplicating info that can be gathered or calculated reasonably easy on the receiving side. Data over the wire should be the minimal unique set of data.

#[prost(uint64, tag = "4")]
pub size: u64,
/// File mode for this entry. For possible flags and values, see enum FileMode.
#[prost(uint64, tag = "5")]
pub mode: u64,
}
impl ::prost::Name for TreeNode {
const NAME: &'static str = "TreeNode";
Expand Down
2 changes: 2 additions & 0 deletions lore-proto/tests/v1_thin_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ fn v1_thin_client_field_shapes() {
path: _,
node_type: _,
address: _,
size: _,
mode: _,
} = TreeNode::default();

// Revision + nested Parent + Metadata
Expand Down
4 changes: 4 additions & 0 deletions lore-revision/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3305,6 +3305,8 @@ pub struct TreePath {
pub path: RelativePath,
pub address: Option<Address>,
pub flags: NodeFlags,
pub size: u64,
pub mode: u64,
}

pub type CanReadRepository = Arc<dyn Fn(RepositoryId) -> bool + Send + Sync>;
Expand Down Expand Up @@ -3466,6 +3468,8 @@ async fn gather_tree_paths_node(
path: node_path.clone(),
address,
flags,
size: node.size,
mode: node.mode as u64,
});

let depth_remaining = max_depth == 0 || depth + 1 < max_depth;
Expand Down
2 changes: 2 additions & 0 deletions lore-server/src/grpc/thinclient/v1/revision_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ async fn stream_tree(
hash: address.hash.into(),
context: address.context.into(),
}),
size: tree_path.size,
mode: tree_path.mode,
};
if tx
.send(Ok(RevisionTreeResponse {
Expand Down