upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/git.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2024-02-21 11:07:38 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2024-02-21 11:07:38 +0000
commit125ead4bb64d9e4a76266aabe5e826fc23551edc (patch)
treead6807af12e11f9fba9d2e04e15e1c56bb5f64b3 /src/git.rs
parent141ebf0cc0c6cfea640debc9b9073303509a8bc7 (diff)
feat(send): specify commits eg HEAD~2
specifiy commits or commit ranges in the same way that `git format-patch` allows
Diffstat (limited to 'src/git.rs')
-rw-r--r--src/git.rs139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/git.rs b/src/git.rs
index 63bce20..d0eaf03 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -67,6 +67,7 @@ pub trait RepoActions {
67 branch_name: &str, 67 branch_name: &str,
68 patch_and_ancestors: Vec<nostr::Event>, 68 patch_and_ancestors: Vec<nostr::Event>,
69 ) -> Result<Vec<nostr::Event>>; 69 ) -> Result<Vec<nostr::Event>>;
70 fn parse_starting_commits(&self, starting_commits: &str) -> Result<Vec<Sha1Hash>>;
70} 71}
71 72
72impl RepoActions for Repo { 73impl RepoActions for Repo {
@@ -407,6 +408,49 @@ impl RepoActions for Repo {
407 } 408 }
408 Ok(patches_to_apply) 409 Ok(patches_to_apply)
409 } 410 }
411
412 fn parse_starting_commits(&self, starting_commits: &str) -> Result<Vec<Sha1Hash>> {
413 let revspec = self
414 .git_repo
415 .revparse(starting_commits)
416 .context("specified value not in a valid format")?;
417 if revspec.mode().is_no_single() {
418 let (ahead, _) = self
419 .get_commits_ahead_behind(
420 &oid_to_sha1(
421 &revspec
422 .from()
423 .context("cannot get starting commit from specified value")?
424 .id(),
425 ),
426 &self
427 .get_head_commit()
428 .context("cannot get head commit with gitlib2")?,
429 )
430 .context("specified commit is not an ancestor of current head")?;
431 Ok(ahead)
432 } else if revspec.mode().is_range() {
433 let (ahead, _) = self
434 .get_commits_ahead_behind(
435 &oid_to_sha1(
436 &revspec
437 .from()
438 .context("cannot get starting commit of range from specified value")?
439 .id(),
440 ),
441 &oid_to_sha1(
442 &revspec
443 .to()
444 .context("cannot get end of range commit from specified value")?
445 .id(),
446 ),
447 )
448 .context("specified commit is not an ancestor of current head")?;
449 Ok(ahead)
450 } else {
451 bail!("specified value not in a supported format")
452 }
453 }
410} 454}
411 455
412fn oid_to_u8_20_bytes(oid: &Oid) -> [u8; 20] { 456fn oid_to_u8_20_bytes(oid: &Oid) -> [u8; 20] {
@@ -1753,4 +1797,99 @@ mod tests {
1753 } 1797 }
1754 } 1798 }
1755 } 1799 }
1800 mod parse_starting_commits {
1801 use super::*;
1802
1803 mod head_1_returns_latest_commit {
1804 use super::*;
1805
1806 #[test]
1807 fn when_on_main_and_other_commits_are_more_recent_on_feature_branch() -> Result<()> {
1808 let test_repo = GitTestRepo::default();
1809 let git_repo = Repo::from_path(&test_repo.dir)?;
1810 test_repo.populate_with_test_branch()?;
1811 test_repo.checkout("main")?;
1812
1813 assert_eq!(
1814 git_repo.parse_starting_commits("HEAD~1")?,
1815 vec![str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?],
1816 );
1817 Ok(())
1818 }
1819
1820 #[test]
1821 fn when_checked_out_branch_ahead_of_main() -> Result<()> {
1822 let test_repo = GitTestRepo::default();
1823 let git_repo = Repo::from_path(&test_repo.dir)?;
1824 test_repo.populate_with_test_branch()?;
1825
1826 assert_eq!(
1827 git_repo.parse_starting_commits("HEAD~1")?,
1828 vec![str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?],
1829 );
1830 Ok(())
1831 }
1832 }
1833 mod head_2_returns_latest_2_commits_youngest_first {
1834 use super::*;
1835
1836 #[test]
1837 fn when_on_main_and_other_commits_are_more_recent_on_feature_branch() -> Result<()> {
1838 let test_repo = GitTestRepo::default();
1839 let git_repo = Repo::from_path(&test_repo.dir)?;
1840 test_repo.populate_with_test_branch()?;
1841 test_repo.checkout("main")?;
1842
1843 assert_eq!(
1844 git_repo.parse_starting_commits("HEAD~2")?,
1845 vec![
1846 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?,
1847 str_to_sha1("af474d8d271490e5c635aad337abdc050034b16a")?,
1848 ],
1849 );
1850 Ok(())
1851 }
1852 }
1853 mod head_3_returns_latest_3_commits_youngest_first {
1854 use super::*;
1855
1856 #[test]
1857 fn when_checked_out_branch_ahead_of_main() -> Result<()> {
1858 let test_repo = GitTestRepo::default();
1859 let git_repo = Repo::from_path(&test_repo.dir)?;
1860 test_repo.populate_with_test_branch()?;
1861
1862 assert_eq!(
1863 git_repo.parse_starting_commits("HEAD~3")?,
1864 vec![
1865 str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?,
1866 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?,
1867 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?,
1868 ],
1869 );
1870 Ok(())
1871 }
1872 }
1873 mod range_of_3_commits_not_in_branch_history_returns_3_commits_youngest_first {
1874 use super::*;
1875
1876 #[test]
1877 fn when_checked_out_branch_ahead_of_main() -> Result<()> {
1878 let test_repo = GitTestRepo::default();
1879 let git_repo = Repo::from_path(&test_repo.dir)?;
1880 test_repo.populate_with_test_branch()?;
1881 test_repo.checkout("main")?;
1882
1883 assert_eq!(
1884 git_repo.parse_starting_commits("af474d8..a23e6b0")?,
1885 vec![
1886 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?,
1887 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?,
1888 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?,
1889 ],
1890 );
1891 Ok(())
1892 }
1893 }
1894 }
1756} 1895}