Skip to main content

lit/commands/
log.rs

1use crate::core::{find_repo_root, get_current_branch, read_head, Object, ObjectHash};
2use crate::response::{CommitEntry, LogResponse};
3use crate::storage::ObjectStore;
4
5pub fn execute(count: usize, _oneline: bool) -> Result<LogResponse, crate::errors::LitError> {
6    let repo_root = find_repo_root()?;
7    let store = ObjectStore::new(&repo_root);
8
9    // Get current HEAD
10    let head_hash = match read_head(&repo_root) {
11        Ok(hash) => hash,
12        Err(_) => {
13            return Ok(LogResponse {
14                branch: get_current_branch(&repo_root).ok(),
15                commits: vec![],
16            });
17        }
18    };
19
20    let current_branch = get_current_branch(&repo_root).ok();
21
22    // Walk commit history
23    let mut commits = Vec::new();
24    let mut current = ObjectHash::from_hex(head_hash.clone());
25
26    for _ in 0..count {
27        match store.read(&current) {
28            Ok(Object::Commit(commit)) => {
29                let is_head = current.to_string() == head_hash;
30                commits.push(CommitEntry {
31                    hash: current.to_string(),
32                    short_hash: current.short().to_string(),
33                    author: commit.author.clone(),
34                    timestamp: commit.timestamp,
35                    message: commit.message.clone(),
36                    is_head,
37                });
38
39                if commit.parents.is_empty() {
40                    break;
41                }
42
43                current = commit.parents[0].clone();
44            }
45            Ok(_) => return Err("Expected commit object".into()),
46            Err(_) => break,
47        }
48    }
49
50    Ok(LogResponse {
51        branch: current_branch,
52        commits,
53    })
54}