From 31d3ff0fdf9e2e1d2232819d7d5331faa63f8f51 Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 29 Apr 2022 19:44:10 +0200 Subject: [PATCH] Add binding for git_commit_body This patch adds a binding for git_commit_body to retrieve the commit message without the summary paragraph. Additionally, this patch updates the test suite to test commits with a body paragraph. While the commit body was previously available via Commit::message, users would have to reimplement libgit2's behaviour to extract the commit body from it. --- libgit2-sys/lib.rs | 1 + src/commit.rs | 27 ++++++++++++++++++++++++++- src/remote.rs | 2 +- src/test.rs | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 195f1371e2..259d5e8df1 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -2747,6 +2747,7 @@ extern "C" { pub fn git_commit_parentcount(commit: *const git_commit) -> c_uint; pub fn git_commit_raw_header(commit: *const git_commit) -> *const c_char; pub fn git_commit_summary(commit: *mut git_commit) -> *const c_char; + pub fn git_commit_body(commit: *mut git_commit) -> *const c_char; pub fn git_commit_time(commit: *const git_commit) -> git_time_t; pub fn git_commit_time_offset(commit: *const git_commit) -> c_int; pub fn git_commit_tree(tree_out: *mut *mut git_tree, commit: *const git_commit) -> c_int; diff --git a/src/commit.rs b/src/commit.rs index b7e900a7ae..c6e2bd10e5 100644 --- a/src/commit.rs +++ b/src/commit.rs @@ -145,6 +145,29 @@ impl<'repo> Commit<'repo> { unsafe { crate::opt_bytes(self, raw::git_commit_summary(self.raw)) } } + /// Get the long "body" of the git commit message. + /// + /// The returned message is the body of the commit, comprising everything + /// but the first paragraph of the message. Leading and trailing whitespaces + /// are trimmed. + /// + /// `None` may be returned if an error occurs or if the summary is not valid + /// utf-8. + pub fn body(&self) -> Option<&str> { + self.body_bytes().and_then(|s| str::from_utf8(s).ok()) + } + + /// Get the long "body" of the git commit message. + /// + /// The returned message is the body of the commit, comprising everything + /// but the first paragraph of the message. Leading and trailing whitespaces + /// are trimmed. + /// + /// `None` may be returned if an error occurs. + pub fn body_bytes(&self) -> Option<&[u8]> { + unsafe { crate::opt_bytes(self, raw::git_commit_body(self.raw)) } + } + /// Get the commit time (i.e. committer time) of a commit. /// /// The first element of the tuple is the time, in seconds, since the epoch. @@ -399,12 +422,14 @@ mod tests { let head = repo.head().unwrap(); let target = head.target().unwrap(); let commit = repo.find_commit(target).unwrap(); - assert_eq!(commit.message(), Some("initial")); + assert_eq!(commit.message(), Some("initial\n\nbody")); + assert_eq!(commit.body(), Some("body")); assert_eq!(commit.id(), target); commit.message_raw().unwrap(); commit.raw_header().unwrap(); commit.message_encoding(); commit.summary().unwrap(); + commit.body().unwrap(); commit.tree_id(); commit.tree().unwrap(); assert_eq!(commit.parents().count(), 0); diff --git a/src/remote.rs b/src/remote.rs index 831e108790..4db06e7e11 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -956,7 +956,7 @@ mod tests { let repo = Repository::clone(&url, td3.path()).unwrap(); let commit = repo.head().unwrap().target().unwrap(); let commit = repo.find_commit(commit).unwrap(); - assert_eq!(commit.message(), Some("initial")); + assert_eq!(commit.message(), Some("initial\n\nbody")); } #[test] diff --git a/src/test.rs b/src/test.rs index 89a13beafe..c1ff1de21f 100644 --- a/src/test.rs +++ b/src/test.rs @@ -31,7 +31,7 @@ pub fn repo_init() -> (TempDir, Repository) { let tree = repo.find_tree(id).unwrap(); let sig = repo.signature().unwrap(); - repo.commit(Some("HEAD"), &sig, &sig, "initial", &tree, &[]) + repo.commit(Some("HEAD"), &sig, &sig, "initial\n\nbody", &tree, &[]) .unwrap(); } (td, repo)