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:
Diffstat (limited to 'src/git.rs')
-rw-r--r--src/git.rs92
1 files changed, 77 insertions, 15 deletions
diff --git a/src/git.rs b/src/git.rs
index 42297be..bb2b8e7 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -32,10 +32,13 @@ impl Repo {
32pub trait RepoActions { 32pub trait RepoActions {
33 fn get_path(&self) -> Result<&Path>; 33 fn get_path(&self) -> Result<&Path>;
34 fn get_origin_url(&self) -> Result<String>; 34 fn get_origin_url(&self) -> Result<String>;
35 fn get_remote_branch_names(&self) -> Result<Vec<String>>;
35 fn get_local_branch_names(&self) -> Result<Vec<String>>; 36 fn get_local_branch_names(&self) -> Result<Vec<String>>;
37 fn get_origin_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)>;
38 fn get_local_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)>;
36 fn get_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)>; 39 fn get_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)>;
37 fn get_checked_out_branch_name(&self) -> Result<String>; 40 fn get_checked_out_branch_name(&self) -> Result<String>;
38 fn get_tip_of_local_branch(&self, branch_name: &str) -> Result<Sha1Hash>; 41 fn get_tip_of_branch(&self, branch_name: &str) -> Result<Sha1Hash>;
39 fn get_root_commit(&self) -> Result<Sha1Hash>; 42 fn get_root_commit(&self) -> Result<Sha1Hash>;
40 fn does_commit_exist(&self, commit: &str) -> Result<bool>; 43 fn does_commit_exist(&self, commit: &str) -> Result<bool>;
41 fn get_head_commit(&self) -> Result<Sha1Hash>; 44 fn get_head_commit(&self) -> Result<Sha1Hash>;
@@ -91,7 +94,30 @@ impl RepoActions for Repo {
91 .to_string()) 94 .to_string())
92 } 95 }
93 96
94 fn get_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)> { 97 fn get_origin_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)> {
98 let main_branch_name = {
99 let remote_branches = self
100 .get_remote_branch_names()
101 .context("cannot find any local branches")?;
102 if remote_branches.contains(&"origin/main".to_string()) {
103 "origin/main"
104 } else if remote_branches.contains(&"origin/master".to_string()) {
105 "origin/master"
106 } else {
107 bail!("no main or master branch locally in this git repository to initiate from",)
108 }
109 };
110
111 let tip = self
112 .get_tip_of_branch(main_branch_name)
113 .context(format!(
114 "branch {main_branch_name} was listed as a remote branch but cannot get its tip commit id",
115 ))?;
116
117 Ok((main_branch_name, tip))
118 }
119
120 fn get_local_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)> {
95 let main_branch_name = { 121 let main_branch_name = {
96 let local_branches = self 122 let local_branches = self
97 .get_local_branch_names() 123 .get_local_branch_names()
@@ -106,7 +132,7 @@ impl RepoActions for Repo {
106 }; 132 };
107 133
108 let tip = self 134 let tip = self
109 .get_tip_of_local_branch(main_branch_name) 135 .get_tip_of_branch(main_branch_name)
110 .context(format!( 136 .context(format!(
111 "branch {main_branch_name} was listed as a local branch but cannot get its tip commit id", 137 "branch {main_branch_name} was listed as a local branch but cannot get its tip commit id",
112 ))?; 138 ))?;
@@ -114,6 +140,18 @@ impl RepoActions for Repo {
114 Ok((main_branch_name, tip)) 140 Ok((main_branch_name, tip))
115 } 141 }
116 142
143 fn get_main_or_master_branch(&self) -> Result<(&str, Sha1Hash)> {
144 if let Ok(main_tuple) = self
145 .get_origin_main_or_master_branch()
146 .context("the default branches (main or master) do not exist")
147 {
148 Ok(main_tuple)
149 } else {
150 self.get_main_or_master_branch()
151 .context("the default branches (main or master) do not exist")
152 }
153 }
154
117 fn get_local_branch_names(&self) -> Result<Vec<String>> { 155 fn get_local_branch_names(&self) -> Result<Vec<String>> {
118 let local_branches = self 156 let local_branches = self
119 .git_repo 157 .git_repo
@@ -131,6 +169,23 @@ impl RepoActions for Repo {
131 Ok(branch_names) 169 Ok(branch_names)
132 } 170 }
133 171
172 fn get_remote_branch_names(&self) -> Result<Vec<String>> {
173 let remote_branches = self
174 .git_repo
175 .branches(Some(git2::BranchType::Remote))
176 .context("getting GitRepo branches should not error even for a blank repository")?;
177
178 let mut branch_names = vec![];
179
180 for iter in remote_branches {
181 let branch = iter?.0;
182 if let Some(name) = branch.name()? {
183 branch_names.push(name.to_string());
184 }
185 }
186 Ok(branch_names)
187 }
188
134 fn get_checked_out_branch_name(&self) -> Result<String> { 189 fn get_checked_out_branch_name(&self) -> Result<String> {
135 Ok(self 190 Ok(self
136 .git_repo 191 .git_repo
@@ -140,11 +195,18 @@ impl RepoActions for Repo {
140 .to_string()) 195 .to_string())
141 } 196 }
142 197
143 fn get_tip_of_local_branch(&self, branch_name: &str) -> Result<Sha1Hash> { 198 fn get_tip_of_branch(&self, branch_name: &str) -> Result<Sha1Hash> {
144 let branch = self 199 let branch = if let Ok(branch) = self
145 .git_repo 200 .git_repo
146 .find_branch(branch_name, git2::BranchType::Local) 201 .find_branch(branch_name, git2::BranchType::Local)
147 .context(format!("cannot find branch {branch_name}"))?; 202 .context(format!("cannot find local branch {branch_name}"))
203 {
204 branch
205 } else {
206 self.git_repo
207 .find_branch(branch_name, git2::BranchType::Remote)
208 .context(format!("cannot find local or remote branch {branch_name}"))?
209 };
148 Ok(oid_to_sha1(&branch.into_reference().peel_to_commit()?.id())) 210 Ok(oid_to_sha1(&branch.into_reference().peel_to_commit()?.id()))
149 } 211 }
150 212
@@ -407,7 +469,7 @@ impl RepoActions for Repo {
407 branch_name: &str, 469 branch_name: &str,
408 patch_and_ancestors: Vec<nostr::Event>, 470 patch_and_ancestors: Vec<nostr::Event>,
409 ) -> Result<Vec<nostr::Event>> { 471 ) -> Result<Vec<nostr::Event>> {
410 let branch_tip_result = self.get_tip_of_local_branch(branch_name); 472 let branch_tip_result = self.get_tip_of_branch(branch_name);
411 473
412 // filter out existing ancestors in branch 474 // filter out existing ancestors in branch
413 let mut patches_to_apply: Vec<nostr::Event> = patch_and_ancestors 475 let mut patches_to_apply: Vec<nostr::Event> = patch_and_ancestors
@@ -1663,7 +1725,7 @@ mod tests {
1663 let git_repo = Repo::from_path(&test_repo.dir)?; 1725 let git_repo = Repo::from_path(&test_repo.dir)?;
1664 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?; 1726 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?;
1665 assert_eq!( 1727 assert_eq!(
1666 git_repo.get_tip_of_local_branch(BRANCH_NAME)?, 1728 git_repo.get_tip_of_branch(BRANCH_NAME)?,
1667 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),), 1729 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),),
1668 ); 1730 );
1669 Ok(()) 1731 Ok(())
@@ -1677,11 +1739,11 @@ mod tests {
1677 let existing_branch = test_repo.get_checked_out_branch_name()?; 1739 let existing_branch = test_repo.get_checked_out_branch_name()?;
1678 let git_repo = Repo::from_path(&test_repo.dir)?; 1740 let git_repo = Repo::from_path(&test_repo.dir)?;
1679 let previous_tip_of_existing_branch = 1741 let previous_tip_of_existing_branch =
1680 git_repo.get_tip_of_local_branch(existing_branch.as_str())?; 1742 git_repo.get_tip_of_branch(existing_branch.as_str())?;
1681 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?; 1743 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?;
1682 assert_eq!( 1744 assert_eq!(
1683 previous_tip_of_existing_branch, 1745 previous_tip_of_existing_branch,
1684 git_repo.get_tip_of_local_branch(existing_branch.as_str())?, 1746 git_repo.get_tip_of_branch(existing_branch.as_str())?,
1685 ); 1747 );
1686 Ok(()) 1748 Ok(())
1687 } 1749 }
@@ -1744,7 +1806,7 @@ mod tests {
1744 let git_repo = Repo::from_path(&test_repo.dir)?; 1806 let git_repo = Repo::from_path(&test_repo.dir)?;
1745 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?; 1807 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?;
1746 assert_eq!( 1808 assert_eq!(
1747 git_repo.get_tip_of_local_branch(BRANCH_NAME)?, 1809 git_repo.get_tip_of_branch(BRANCH_NAME)?,
1748 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),), 1810 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),),
1749 ); 1811 );
1750 Ok(()) 1812 Ok(())
@@ -1760,11 +1822,11 @@ mod tests {
1760 let existing_branch = test_repo.get_checked_out_branch_name()?; 1822 let existing_branch = test_repo.get_checked_out_branch_name()?;
1761 let git_repo = Repo::from_path(&test_repo.dir)?; 1823 let git_repo = Repo::from_path(&test_repo.dir)?;
1762 let previous_tip_of_existing_branch = 1824 let previous_tip_of_existing_branch =
1763 git_repo.get_tip_of_local_branch(existing_branch.as_str())?; 1825 git_repo.get_tip_of_branch(existing_branch.as_str())?;
1764 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?; 1826 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?;
1765 assert_eq!( 1827 assert_eq!(
1766 previous_tip_of_existing_branch, 1828 previous_tip_of_existing_branch,
1767 git_repo.get_tip_of_local_branch(existing_branch.as_str())?, 1829 git_repo.get_tip_of_branch(existing_branch.as_str())?,
1768 ); 1830 );
1769 Ok(()) 1831 Ok(())
1770 } 1832 }
@@ -1800,7 +1862,7 @@ mod tests {
1800 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?; 1862 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?;
1801 1863
1802 assert_eq!( 1864 assert_eq!(
1803 git_repo.get_tip_of_local_branch(BRANCH_NAME)?, 1865 git_repo.get_tip_of_branch(BRANCH_NAME)?,
1804 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),), 1866 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),),
1805 ); 1867 );
1806 Ok(()) 1868 Ok(())
@@ -1832,7 +1894,7 @@ mod tests {
1832 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?; 1894 git_repo.apply_patch_chain(BRANCH_NAME, patch_events)?;
1833 1895
1834 assert_eq!( 1896 assert_eq!(
1835 git_repo.get_tip_of_local_branch(BRANCH_NAME)?, 1897 git_repo.get_tip_of_branch(BRANCH_NAME)?,
1836 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),), 1898 oid_to_sha1(&original_repo.git_repo.head()?.peel_to_commit()?.id(),),
1837 ); 1899 );
1838 Ok(()) 1900 Ok(())