|
| 1 | +use crate::{init_opts, VAR_NO_CLEANUP}; |
| 2 | +use gitbutler_oxidize::{git2_to_gix_object_id, gix_to_git2_oid}; |
1 | 3 | use gitbutler_reference::{LocalRefname, Refname}; |
2 | | -use gitbutler_repo::RepositoryExt; |
| 4 | +use gitbutler_repo::{GixRepositoryExt, RepositoryExt}; |
3 | 5 | use std::{fs, path, path::PathBuf}; |
4 | 6 | use tempfile::TempDir; |
5 | 7 |
|
6 | | -use crate::{init_opts, VAR_NO_CLEANUP}; |
7 | | - |
8 | 8 | pub fn temp_dir() -> TempDir { |
9 | 9 | tempfile::tempdir().unwrap() |
10 | 10 | } |
@@ -214,64 +214,60 @@ impl TestProject { |
214 | 214 | } |
215 | 215 |
|
216 | 216 | /// works like if we'd open and merge a PR on github. does not update local. |
217 | | - pub fn merge(&self, branch_name: &Refname) { |
| 217 | + pub fn merge(&self, branch_name: &Refname) -> anyhow::Result<()> { |
218 | 218 | let branch_name: Refname = match branch_name { |
219 | | - Refname::Local(local) => format!("refs/heads/{}", local.branch()).parse().unwrap(), |
220 | | - Refname::Remote(remote) => format!("refs/heads/{}", remote.branch()).parse().unwrap(), |
221 | | - _ => "INVALID".parse().unwrap(), // todo |
| 219 | + Refname::Local(local) => format!("refs/heads/{}", local.branch()).parse()?, |
| 220 | + Refname::Remote(remote) => format!("refs/heads/{}", remote.branch()).parse()?, |
| 221 | + _ => "INVALID".parse()?, // todo |
222 | 222 | }; |
223 | 223 | let branch = self |
224 | 224 | .remote_repository |
225 | | - .maybe_find_branch_by_refname(&branch_name) |
226 | | - .unwrap(); |
227 | | - let branch_commit = branch.as_ref().unwrap().get().peel_to_commit().unwrap(); |
| 225 | + .maybe_find_branch_by_refname(&branch_name)? |
| 226 | + .expect("branch exists"); |
| 227 | + let branch_commit = branch.get().peel_to_commit()?; |
228 | 228 |
|
229 | 229 | let master_branch = { |
230 | | - let name: Refname = "refs/heads/master".parse().unwrap(); |
231 | | - self.remote_repository |
232 | | - .maybe_find_branch_by_refname(&name) |
233 | | - .unwrap() |
| 230 | + let name: Refname = "refs/heads/master".parse()?; |
| 231 | + self.remote_repository.maybe_find_branch_by_refname(&name)? |
234 | 232 | }; |
235 | 233 | let master_branch_commit = master_branch |
236 | 234 | .as_ref() |
237 | | - .unwrap() |
| 235 | + .expect("master branch exists") |
238 | 236 | .get() |
239 | | - .peel_to_commit() |
240 | | - .unwrap(); |
| 237 | + .peel_to_commit()?; |
241 | 238 |
|
242 | | - let merge_base = { |
243 | | - let oid = self |
244 | | - .remote_repository |
245 | | - .merge_base(branch_commit.id(), master_branch_commit.id()) |
246 | | - .unwrap(); |
247 | | - self.remote_repository.find_commit(oid).unwrap() |
248 | | - }; |
| 239 | + let gix_repo = gix::open_opts( |
| 240 | + self.remote_repository.path(), |
| 241 | + gix::open::Options::isolated(), |
| 242 | + )?; |
249 | 243 | let merge_tree = { |
250 | | - let mut merge_index = self |
251 | | - .remote_repository |
252 | | - .merge_trees( |
253 | | - &merge_base.tree().unwrap(), |
254 | | - &master_branch.unwrap().get().peel_to_tree().unwrap(), |
255 | | - &branch.unwrap().get().peel_to_tree().unwrap(), |
256 | | - None, |
257 | | - ) |
258 | | - .unwrap(); |
259 | | - let repo: &git2::Repository = &self.remote_repository; |
260 | | - let oid = merge_index.write_tree_to(repo).unwrap(); |
261 | | - self.remote_repository.find_tree(oid).unwrap() |
| 244 | + let mut merge_result = gix_repo.merge_commits( |
| 245 | + git2_to_gix_object_id(master_branch_commit.id()), |
| 246 | + git2_to_gix_object_id(branch.get().peel_to_commit()?.id()), |
| 247 | + gix_repo.default_merge_labels(), |
| 248 | + gix::merge::commit::Options::default(), |
| 249 | + )?; |
| 250 | + assert!( |
| 251 | + !merge_result |
| 252 | + .tree_merge |
| 253 | + .has_unresolved_conflicts(Default::default()), |
| 254 | + "test-merges should have non-conflicting trees" |
| 255 | + ); |
| 256 | + let tree_id = merge_result.tree_merge.tree.write()?; |
| 257 | + self.remote_repository.find_tree(gix_to_git2_oid(tree_id))? |
262 | 258 | }; |
263 | 259 |
|
264 | 260 | let repo: &git2::Repository = &self.remote_repository; |
265 | 261 | repo.commit_with_signature( |
266 | | - Some(&"refs/heads/master".parse().unwrap()), |
| 262 | + Some(&"refs/heads/master".parse()?), |
267 | 263 | &branch_commit.author(), |
268 | 264 | &branch_commit.committer(), |
269 | 265 | &format!("Merge pull request from {}", branch_name), |
270 | 266 | &merge_tree, |
271 | 267 | &[&master_branch_commit, &branch_commit], |
272 | 268 | None, |
273 | | - ) |
274 | | - .unwrap(); |
| 269 | + )?; |
| 270 | + Ok(()) |
275 | 271 | } |
276 | 272 |
|
277 | 273 | pub fn find_commit(&self, oid: git2::Oid) -> Result<git2::Commit<'_>, git2::Error> { |
|
0 commit comments