Repository navigation
fix: replace panic!() in tree.rs with proper error propagation #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,4 @@ | ||||||||||||||||||||||||
| use anyhow::Result; | ||||||||||||||||||||||||
| use anyhow::{bail, Result}; | ||||||||||||||||||||||||
| use git2::{FileMode, Oid, Repository, Signature, Time}; | ||||||||||||||||||||||||
| use std::collections::HashMap; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -24,7 +24,7 @@ impl TreeNode { | |||||||||||||||||||||||
| self.cached_oid = None; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| pub fn insert_blob(&mut self, path: &str, blob_oid: Oid) { | ||||||||||||||||||||||||
| pub fn insert_blob(&mut self, path: &str, blob_oid: Oid) -> Result<()> { | ||||||||||||||||||||||||
| self.invalidate(); | ||||||||||||||||||||||||
| if let Some(slash) = path.find('/') { | ||||||||||||||||||||||||
| let dir = &path[..slash]; | ||||||||||||||||||||||||
|
|
@@ -34,13 +34,16 @@ impl TreeNode { | |||||||||||||||||||||||
| .entry(dir.to_string()) | ||||||||||||||||||||||||
| .or_insert_with(|| TreeEntry::Tree(TreeNode::new())); | ||||||||||||||||||||||||
| match child { | ||||||||||||||||||||||||
| TreeEntry::Tree(node) => node.insert_blob(rest, blob_oid), | ||||||||||||||||||||||||
| _ => panic!("path conflict: {dir} is a blob, not a tree"), | ||||||||||||||||||||||||
| TreeEntry::Tree(node) => node.insert_blob(rest, blob_oid)?, | ||||||||||||||||||||||||
| _ => { | ||||||||||||||||||||||||
| bail!("path conflict: '{dir}' is a blob, not a tree (while inserting '{path}')") | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+37
to
+40
|
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||
| self.entries | ||||||||||||||||||||||||
| .insert(path.to_string(), TreeEntry::Blob(blob_oid)); | ||||||||||||||||||||||||
|
Comment on lines
43
to
44
|
||||||||||||||||||||||||
| self.entries | |
| .insert(path.to_string(), TreeEntry::Blob(blob_oid)); | |
| match self.entries.get(path) { | |
| Some(TreeEntry::Tree(_)) => { | |
| bail!("path conflict: '{path}' is a tree, not a blob") | |
| } | |
| Some(TreeEntry::Blob(_)) | None => { | |
| self.entries | |
| .insert(path.to_string(), TreeEntry::Blob(blob_oid)); | |
| } | |
| } |
Copilot
AI
Apr 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new test only asserts the error contains the generic substring "path conflict". Since the PR goal is a descriptive message including the conflicting path, consider asserting that the error string also contains the conflicting segment (e.g. "f") and/or the attempted path (e.g. "f/g.txt") so regressions in the message content are caught.
| assert!(err.to_string().contains("path conflict")); | |
| let err_str = err.to_string(); | |
| assert!(err_str.contains("path conflict")); | |
| assert!(err_str.contains("f")); | |
| assert!(err_str.contains("f/g.txt")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.invalidate()runs before any conflict checks. On a conflict this leaves the tree logically unchanged but clearscached_oid, causing unnecessary recomputation if the caller recovers and continues. Consider invalidating only after a successful insertion (or only on the branch where a mutation actually happens).