diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-02-21 11:07:38 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-02-21 11:07:38 +0000 |
| commit | 125ead4bb64d9e4a76266aabe5e826fc23551edc (patch) | |
| tree | ad6807af12e11f9fba9d2e04e15e1c56bb5f64b3 /src/git.rs | |
| parent | 141ebf0cc0c6cfea640debc9b9073303509a8bc7 (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.rs | 139 |
1 files changed, 139 insertions, 0 deletions
| @@ -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 | ||
| 72 | impl RepoActions for Repo { | 73 | impl 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 | ||
| 412 | fn oid_to_u8_20_bytes(oid: &Oid) -> [u8; 20] { | 456 | fn 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 | } |