Skip to content
Merged
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
128 changes: 68 additions & 60 deletions src/commands/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,77 +49,85 @@ fn collect_files_recursively(dir: &PathBuf) -> Result<Vec<PathBuf>> {
/// Main function for the `guts add` command
/// Adds files to the staging area (index)
pub fn run(args: &AddArgs) -> Result<String> {
// Determine current directory to use
let current_dir = args
.dir
.clone()
.unwrap_or_else(|| std::env::current_dir().expect("failed to get current directory"));

// Check if we're in a git repository
if !simple_index::is_git_repository_from(Some(&current_dir))? {
return Err(anyhow!("fatal: not a git repository"));
// Set current directory context for TUI
let original_dir = std::env::current_dir()?;
if let Some(dir) = &args.dir {
std::env::set_current_dir(dir)?;
}

let result = || -> Result<String> {
// Check if we're in a git repository
if !simple_index::is_git_repository()? {
return Err(anyhow!("fatal: not a git repository"));
}

let mut added_files = Vec::new();
let mut output = String::new();

// Load .gutsignore matcher
let matcher = IgnoreMatcher::from_gutsignore(&current_dir)
.unwrap_or_else(|_| IgnoreMatcher::empty());

// Process each requested file
for file_path in &args.files {
// Support for "." - add all files from current directory
if file_path.to_string_lossy() == "." {
let files = collect_files_recursively(&current_dir)?;
for file in files {
if matcher.is_ignored(&file, &current_dir) {
continue;
let mut added_files = Vec::new();
let mut output = String::new();
let current_dir = std::env::current_dir()?;

// Load .gutsignore matcher
let matcher = IgnoreMatcher::from_gutsignore(&current_dir)
.unwrap_or_else(|_| IgnoreMatcher::empty());

// Process each requested file
for file_path in &args.files {
// Support for "." - add all files from current directory
if file_path.to_string_lossy() == "." {
let files = collect_files_recursively(&current_dir)?;
for file in files {
if matcher.is_ignored(&file, &current_dir) {
continue;
}
simple_index::add_file_to_index(&file)?;
added_files.push(file.display().to_string());
}
simple_index::add_file_to_index_from(&file, Some(&current_dir))?;
added_files.push(file.display().to_string());
continue;
}
continue;
}

// Basic checks
if !file_path.exists() {
return Err(anyhow!(
"pathspec '{}' did not match any files",
file_path.display()
));
}
// Basic checks
if !file_path.exists() {
return Err(anyhow!(
"pathspec '{}' did not match any files",
file_path.display()
));
}

if file_path.is_dir() {
// If it's a directory, add all files recursively
let files = collect_files_recursively(file_path)?;
for file in files {
if matcher.is_ignored(&file, &current_dir) {
if file_path.is_dir() {
// If it's a directory, add all files recursively
let files = collect_files_recursively(file_path)?;
for file in files {
if matcher.is_ignored(&file, &current_dir) {
continue;
}
simple_index::add_file_to_index(&file)?;
added_files.push(file.display().to_string());
}
} else {
// Skip if ignored
if matcher.is_ignored(file_path, &current_dir) {
continue;
}
simple_index::add_file_to_index_from(&file, Some(&current_dir))?;
added_files.push(file.display().to_string());
}
} else {
// Skip if ignored
if matcher.is_ignored(file_path, &current_dir) {
continue;
// Add the file to the JSON index
simple_index::add_file_to_index(file_path)?;
added_files.push(file_path.display().to_string());
}
// Add the file to the JSON index
simple_index::add_file_to_index_from(file_path, Some(&current_dir))?;
added_files.push(file_path.display().to_string());
}
}

// Confirmation message
if added_files.len() == 1 {
output.push_str(&format!("Added: {}", added_files[0]));
} else {
output.push_str(&format!("Added {} files:", added_files.len()));
for file in &added_files {
output.push_str(&format!("\n - {}", file));
// Confirmation message
if added_files.len() == 1 {
output.push_str(&format!("Added: {}", added_files[0]));
} else {
output.push_str(&format!("Added {} files:", added_files.len()));
for file in &added_files {
output.push_str(&format!("\n - {}", file));
}
}
}

Ok(output)
Ok(output)
}();

// Restore original directory
std::env::set_current_dir(&original_dir)?;

result
}
2 changes: 1 addition & 1 deletion src/commands/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn run(args: &CommitArgs) -> Result<String> {

fn run_commit(args: &CommitArgs) -> Result<String> {
// Check if we're in a git repository
if !simple_index::is_git_repository_from(args.dir.as_ref())? {
if !simple_index::is_git_repository()? {
return Err(anyhow::anyhow!("fatal: not a git repository"));
}

Expand Down
29 changes: 19 additions & 10 deletions src/commands/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@ pub struct LogArgs {
/// Entry point for the `guts log` command
/// Traverses the commit chain from HEAD to root, printing each commit's SHA and first line of message.
pub fn run(args: &LogArgs) -> Result<String> {
// Determine current directory to use
let current_dir = args
.dir
.clone()
.unwrap_or_else(|| std::env::current_dir().expect("failed to get current directory"));

// Check if we're in a git repository
if !simple_index::is_git_repository_from(args.dir.as_ref())? {
return Err(anyhow!("fatal: not a git repository"));
// Set current directory context for TUI
let original_dir = std::env::current_dir()?;
if let Some(dir) = &args.dir {
std::env::set_current_dir(dir)?;
}

let result = || -> Result<String> {
// Check if we're in a git repository
if !simple_index::is_git_repository()? {
return Err(anyhow!("fatal: not a git repository"));
}

let current_dir = std::env::current_dir()?;

// Use the standard .git directory
let git_dir = current_dir.join(".git");
Expand Down Expand Up @@ -79,7 +82,13 @@ pub fn run(args: &LogArgs) -> Result<String> {
}
}

Ok(output)
Ok(output)
}();

// Restore original directory
std::env::set_current_dir(&original_dir)?;

result
}


Expand Down
21 changes: 17 additions & 4 deletions src/commands/rm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,17 @@ fn remove_file_from_index(file_path: &PathBuf) -> Result<bool> {
/// Main function for the `guts rm` command
/// Removes files from working directory and index
pub fn run(args: &RmArgs) -> Result<String> {
// Check if we're in a git repository
if !simple_index::is_git_repository_from(args.dir.as_ref())? {
return Err(anyhow!("fatal: not a git repository"));
// Set current directory context for TUI
let original_dir = std::env::current_dir()?;
if let Some(dir) = &args.dir {
std::env::set_current_dir(dir)?;
}

let result = || -> Result<String> {
// Check if we're in a git repository
if !simple_index::is_git_repository()? {
return Err(anyhow!("fatal: not a git repository"));
}

let mut removed_files = Vec::new();
let mut output = String::new();
Expand Down Expand Up @@ -100,5 +107,11 @@ pub fn run(args: &RmArgs) -> Result<String> {
output.pop(); // Remove last newline
}

Ok(output)
Ok(output)
}();

// Restore original directory
std::env::set_current_dir(&original_dir)?;

result
}
45 changes: 27 additions & 18 deletions src/commands/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,23 @@ pub struct StatusObject {

/// Entry point for the `guts status` command
pub fn run(args: &StatusObject) -> Result<String> {
let current_dir = args
.dir
.clone()
.unwrap_or_else(|| std::env::current_dir().expect("failed to get current directory"));

if !simple_index::is_git_repository_from(Some(&current_dir))? {
return Ok("fatal: not a git repository".to_string());
// Set current directory context for TUI
let original_dir = std::env::current_dir()?;
if let Some(dir) = &args.dir {
std::env::set_current_dir(dir)?;
}

let result = || -> Result<String> {
if !simple_index::is_git_repository()? {
return Ok("fatal: not a git repository".to_string());
}

let matcher = IgnoreMatcher::from_gutsignore(&current_dir)
.unwrap_or_else(|_| IgnoreMatcher::empty());
let current_dir = std::env::current_dir()?;
let matcher = IgnoreMatcher::from_gutsignore(&current_dir)
.unwrap_or_else(|_| IgnoreMatcher::empty());

let committed_files = simple_index::get_committed_files_from(Some(&current_dir))?;
let index = simple_index::SimpleIndex::load_from(Some(&current_dir))?;
let committed_files = simple_index::get_committed_files()?;
let index = simple_index::SimpleIndex::load()?;
let work_files = list_working_dir_files(&current_dir, &matcher)?;

let current_branch = read_head::get_current_branch()
Expand Down Expand Up @@ -121,11 +124,17 @@ pub fn run(args: &StatusObject) -> Result<String> {
output.push_str("\n");
}

if staged_changes.is_empty() && unstaged_changes.is_empty() && untracked_files.is_empty() {
output.push_str("nothing to commit, working tree clean\n");
}
if staged_changes.is_empty() && unstaged_changes.is_empty() && untracked_files.is_empty() {
output.push_str("nothing to commit, working tree clean\n");
}

Ok(output)
Ok(output)
}();

// Restore original directory
std::env::set_current_dir(&original_dir)?;

result
}

/// List all working directory files, excluding ignored and .git files
Expand Down Expand Up @@ -153,9 +162,9 @@ fn list_working_dir_files(current_dir: &PathBuf, matcher: &IgnoreMatcher) -> Res
Ok(files)
}

fn get_relative_path(file_path: &PathBuf, current_dir: &PathBuf) -> Result<String> {
// Find repo root from current directory context
let repo_root = simple_index::find_repo_root_from(Some(current_dir))?;
fn get_relative_path(file_path: &PathBuf, _current_dir: &PathBuf) -> Result<String> {
// Find repo root from current working directory
let repo_root = simple_index::find_repo_root()?;
let relative = file_path
.strip_prefix(&repo_root)
.map_err(|_| anyhow::anyhow!("file is not in the repository"))?;
Expand Down
21 changes: 17 additions & 4 deletions src/commands/write_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ pub struct WriteTreeArgs {
/// New version of write-tree that uses the simple JSON index
/// Instead of reading the filesystem, reads the index to create the tree
pub fn run(args: &WriteTreeArgs) -> Result<String> {
// Check if we're in a git repository
if !simple_index::is_git_repository_from(args.dir.as_ref())? {
return Err(anyhow::anyhow!("fatal: not a git repository"));
// Set current directory context for TUI
let original_dir = std::env::current_dir()?;
if let Some(dir) = &args.dir {
std::env::set_current_dir(dir)?;
}

let result = || -> Result<String> {
// Check if we're in a git repository
if !simple_index::is_git_repository()? {
return Err(anyhow::anyhow!("fatal: not a git repository"));
}

// Load the JSON index
let index = simple_index::SimpleIndex::load()?;
Expand All @@ -26,7 +33,13 @@ pub fn run(args: &WriteTreeArgs) -> Result<String> {
// Write the tree object and return its hash
let oid = hash::write_object(&tree)?;

Ok(oid)
Ok(oid)
}();

// Restore original directory
std::env::set_current_dir(&original_dir)?;

result
}

/// Build a Git tree object from the JSON index
Expand Down
Loading