diff --git a/README.md b/README.md index 57042d7..1aa4cd1 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ lumen explain HEAD # Latest commit lumen explain abc123f # Specific commit lumen explain HEAD~3..HEAD # Last 3 commits lumen explain main..feature/A # Branch comparison +lumen explain main...feature/A # Branch comparison (merge base) # Ask specific questions about changes lumen explain --diff --query "What's the performance impact of these changes?" diff --git a/src/commit_reference.rs b/src/commit_reference.rs index e80d625..fd11cbf 100644 --- a/src/commit_reference.rs +++ b/src/commit_reference.rs @@ -5,6 +5,7 @@ use thiserror::Error; pub enum CommitReference { Single(String), Range { from: String, to: String }, + TripleDots { from: String, to: String }, } #[derive(Debug, Error)] @@ -21,8 +22,16 @@ impl FromStr for CommitReference { return Err(ReferenceParseError::Empty); } - // Handle the .. cases - if let Some((from, to)) = s.split_once("..") { + // Handle the ... and .. cases + if let Some((from, to)) = s.split_once("...") { + let from = if from.is_empty() { "HEAD" } else { from }; + let to = if to.is_empty() { "HEAD" } else { to }; + + Ok(CommitReference::TripleDots { + from: from.to_string(), + to: to.to_string(), + }) + } else if let Some((from, to)) = s.split_once("..") { let from = if from.is_empty() { "HEAD" } else { from }; let to = if to.is_empty() { "HEAD" } else { to }; diff --git a/src/git_entity/diff.rs b/src/git_entity/diff.rs index 937afbd..bff97aa 100644 --- a/src/git_entity/diff.rs +++ b/src/git_entity/diff.rs @@ -40,12 +40,15 @@ impl Diff { Ok(Diff::WorkingTree { staged, diff }) } - pub fn from_commits_range(from: &str, to: &str) -> Result { + pub fn from_commits_range(from: &str, to: &str, triple_dot: bool) -> Result { let _ = Commit::is_valid_commit(from)?; let _ = Commit::is_valid_commit(to)?; + let separator = if triple_dot { "..." } else { ".." }; + let range = format!("{}{}{}", from, separator, to); + let output = std::process::Command::new("git") - .args(["diff", from, to]) + .args(["diff", &range]) .output()?; let diff = String::from_utf8(output.stdout)?; diff --git a/src/main.rs b/src/main.rs index b5caef3..0822a03 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,7 +53,9 @@ async fn run() -> Result<(), LumenError> { }; GitEntity::Commit(Commit::new(sha)?) } else if let Some(CommitReference::Range { from, to }) = reference { - GitEntity::Diff(Diff::from_commits_range(&from, &to)?) + GitEntity::Diff(Diff::from_commits_range(&from, &to, false)?) + } else if let Some(CommitReference::TripleDots { from, to }) = reference { + GitEntity::Diff(Diff::from_commits_range(&from, &to, true)?) } else { return Err(LumenError::InvalidArguments( "`explain` expects SHA-1 or --diff to be present".into(),