diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-03-08 14:37:56 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-03-08 14:39:21 +0000 |
| commit | 6b3aecbcbde669859533716225e9c3bbfd2023b2 (patch) | |
| tree | 06258c93893c57ae1ef3b3d709c364f00365fdb5 /src/git.rs | |
| parent | 5622e384447fba354548aca0e39dcee3d95951c3 (diff) | |
feat(send): select commits from a list
when since_or_range isn't specified
adds resilience as assuming master..HEAD can cause some issues
eg when master is not up-to-date with origin/master
Diffstat (limited to 'src/git.rs')
| -rw-r--r-- | src/git.rs | 74 |
1 files changed, 74 insertions, 0 deletions
| @@ -41,6 +41,7 @@ pub trait RepoActions { | |||
| 41 | fn get_head_commit(&self) -> Result<Sha1Hash>; | 41 | fn get_head_commit(&self) -> Result<Sha1Hash>; |
| 42 | fn get_commit_parent(&self, commit: &Sha1Hash) -> Result<Sha1Hash>; | 42 | fn get_commit_parent(&self, commit: &Sha1Hash) -> Result<Sha1Hash>; |
| 43 | fn get_commit_message(&self, commit: &Sha1Hash) -> Result<String>; | 43 | fn get_commit_message(&self, commit: &Sha1Hash) -> Result<String>; |
| 44 | fn get_commit_message_summary(&self, commit: &Sha1Hash) -> Result<String>; | ||
| 44 | /// returns vector ["name", "email", "unixtime", "offset"] | 45 | /// returns vector ["name", "email", "unixtime", "offset"] |
| 45 | /// eg ["joe bloggs", "joe@pm.me", "12176","-300"] | 46 | /// eg ["joe bloggs", "joe@pm.me", "12176","-300"] |
| 46 | fn get_commit_author(&self, commit: &Sha1Hash) -> Result<Vec<String>>; | 47 | fn get_commit_author(&self, commit: &Sha1Hash) -> Result<Vec<String>>; |
| @@ -52,6 +53,7 @@ pub trait RepoActions { | |||
| 52 | base_commit: &Sha1Hash, | 53 | base_commit: &Sha1Hash, |
| 53 | latest_commit: &Sha1Hash, | 54 | latest_commit: &Sha1Hash, |
| 54 | ) -> Result<(Vec<Sha1Hash>, Vec<Sha1Hash>)>; | 55 | ) -> Result<(Vec<Sha1Hash>, Vec<Sha1Hash>)>; |
| 56 | fn get_refs(&self, commit: &Sha1Hash) -> Result<Vec<String>>; | ||
| 55 | // including (un)staged changes and (un)tracked files | 57 | // including (un)staged changes and (un)tracked files |
| 56 | fn has_outstanding_changes(&self) -> Result<bool>; | 58 | fn has_outstanding_changes(&self) -> Result<bool>; |
| 57 | fn make_patch_from_commit( | 59 | fn make_patch_from_commit( |
| @@ -199,6 +201,22 @@ impl RepoActions for Repo { | |||
| 199 | .to_string()) | 201 | .to_string()) |
| 200 | } | 202 | } |
| 201 | 203 | ||
| 204 | fn get_commit_message_summary(&self, commit: &Sha1Hash) -> Result<String> { | ||
| 205 | Ok(self | ||
| 206 | .git_repo | ||
| 207 | .find_commit(sha1_to_oid(commit)?) | ||
| 208 | .context(format!("could not find commit {commit}"))? | ||
| 209 | .message_raw() | ||
| 210 | .context("commit message has unusual characters in (not valid utf-8)")? | ||
| 211 | .split('\r') | ||
| 212 | .collect::<Vec<&str>>()[0] | ||
| 213 | .split('\n') | ||
| 214 | .collect::<Vec<&str>>()[0] | ||
| 215 | .to_string() | ||
| 216 | .trim() | ||
| 217 | .to_string()) | ||
| 218 | } | ||
| 219 | |||
| 202 | fn get_commit_author(&self, commit: &Sha1Hash) -> Result<Vec<String>> { | 220 | fn get_commit_author(&self, commit: &Sha1Hash) -> Result<Vec<String>> { |
| 203 | let commit = self | 221 | let commit = self |
| 204 | .git_repo | 222 | .git_repo |
| @@ -217,6 +235,25 @@ impl RepoActions for Repo { | |||
| 217 | Ok(git_sig_to_tag_vec(&sig)) | 235 | Ok(git_sig_to_tag_vec(&sig)) |
| 218 | } | 236 | } |
| 219 | 237 | ||
| 238 | fn get_refs(&self, commit: &Sha1Hash) -> Result<Vec<String>> { | ||
| 239 | Ok(self | ||
| 240 | .git_repo | ||
| 241 | .references()? | ||
| 242 | .filter(|r| { | ||
| 243 | if let Ok(r) = r { | ||
| 244 | if let Ok(ref_tip) = r.peel_to_commit() { | ||
| 245 | ref_tip.id().to_string().eq(&commit.to_string()) | ||
| 246 | } else { | ||
| 247 | false | ||
| 248 | } | ||
| 249 | } else { | ||
| 250 | false | ||
| 251 | } | ||
| 252 | }) | ||
| 253 | .map(|r| r.unwrap().shorthand().unwrap().to_string()) | ||
| 254 | .collect::<Vec<String>>()) | ||
| 255 | } | ||
| 256 | |||
| 220 | fn make_patch_from_commit( | 257 | fn make_patch_from_commit( |
| 221 | &self, | 258 | &self, |
| 222 | commit: &Sha1Hash, | 259 | commit: &Sha1Hash, |
| @@ -744,6 +781,43 @@ mod tests { | |||
| 744 | } | 781 | } |
| 745 | } | 782 | } |
| 746 | 783 | ||
| 784 | mod get_commit_message_summary { | ||
| 785 | use super::*; | ||
| 786 | fn run(message: &str, summary: &str) -> Result<()> { | ||
| 787 | let test_repo = GitTestRepo::default(); | ||
| 788 | test_repo.populate()?; | ||
| 789 | std::fs::write(test_repo.dir.join("t100.md"), "some content")?; | ||
| 790 | let oid = test_repo.stage_and_commit(message)?; | ||
| 791 | |||
| 792 | let git_repo = Repo::from_path(&test_repo.dir)?; | ||
| 793 | |||
| 794 | assert_eq!( | ||
| 795 | summary, | ||
| 796 | git_repo.get_commit_message_summary(&oid_to_sha1(&oid))?, | ||
| 797 | ); | ||
| 798 | Ok(()) | ||
| 799 | } | ||
| 800 | #[test] | ||
| 801 | fn one_liner() -> Result<()> { | ||
| 802 | run("add t100.md", "add t100.md") | ||
| 803 | } | ||
| 804 | |||
| 805 | #[test] | ||
| 806 | fn multiline() -> Result<()> { | ||
| 807 | run("add t100.md\r\nanother line\r\nthird line", "add t100.md") | ||
| 808 | } | ||
| 809 | |||
| 810 | #[test] | ||
| 811 | fn trailing_newlines() -> Result<()> { | ||
| 812 | run("add t100.md\r\n\r\n\r\n\r\n\r\n\r\n", "add t100.md") | ||
| 813 | } | ||
| 814 | |||
| 815 | #[test] | ||
| 816 | fn unicode_characters() -> Result<()> { | ||
| 817 | run("add t100.md ❤️", "add t100.md ❤️") | ||
| 818 | } | ||
| 819 | } | ||
| 820 | |||
| 747 | mod get_commit_author { | 821 | mod get_commit_author { |
| 748 | use super::*; | 822 | use super::*; |
| 749 | 823 | ||