diff options
| -rw-r--r-- | src/git.rs | 115 |
1 files changed, 106 insertions, 9 deletions
| @@ -370,16 +370,21 @@ impl RepoActions for Repo { | |||
| 370 | branch_name: &str, | 370 | branch_name: &str, |
| 371 | patch_and_ancestors: Vec<nostr::Event>, | 371 | patch_and_ancestors: Vec<nostr::Event>, |
| 372 | ) -> Result<Vec<nostr::Event>> { | 372 | ) -> Result<Vec<nostr::Event>> { |
| 373 | let branch_tip = self.get_tip_of_local_branch(branch_name)?; | 373 | let branch_tip_result = self.get_tip_of_local_branch(branch_name); |
| 374 | |||
| 374 | // filter out existing ancestors in branch | 375 | // filter out existing ancestors in branch |
| 375 | let mut patches_to_apply: Vec<nostr::Event> = patch_and_ancestors | 376 | let mut patches_to_apply: Vec<nostr::Event> = patch_and_ancestors |
| 376 | .into_iter() | 377 | .into_iter() |
| 377 | .filter(|e| { | 378 | .filter(|e| { |
| 378 | let commit_id = get_commit_id_from_patch(e).unwrap(); | 379 | let commit_id = get_commit_id_from_patch(e).unwrap(); |
| 379 | !branch_tip.to_string().eq(&commit_id) | 380 | if let Ok(branch_tip) = branch_tip_result { |
| 380 | || !self | 381 | !branch_tip.to_string().eq(&commit_id) |
| 381 | .ancestor_of(&branch_tip, &str_to_sha1(&commit_id).unwrap()) | 382 | && !self |
| 382 | .unwrap() | 383 | .ancestor_of(&branch_tip, &str_to_sha1(&commit_id).unwrap()) |
| 384 | .unwrap() | ||
| 385 | } else { | ||
| 386 | true | ||
| 387 | } | ||
| 383 | }) | 388 | }) |
| 384 | .collect(); | 389 | .collect(); |
| 385 | 390 | ||
| @@ -387,7 +392,8 @@ impl RepoActions for Repo { | |||
| 387 | if let Ok(last_patch) = patches_to_apply.last().context("no patches") { | 392 | if let Ok(last_patch) = patches_to_apply.last().context("no patches") { |
| 388 | last_patch | 393 | last_patch |
| 389 | } else { | 394 | } else { |
| 390 | self.checkout(branch_name).context("the parent commit of the proposal doesnt exist in your local repoistory. Try a git pull on master first.")?; | 395 | self.checkout(branch_name) |
| 396 | .context("no patches and so cannot create a proposal branch")?; | ||
| 391 | return Ok(vec![]); | 397 | return Ok(vec![]); |
| 392 | }, | 398 | }, |
| 393 | "parent-commit", | 399 | "parent-commit", |
| @@ -399,9 +405,7 @@ impl RepoActions for Repo { | |||
| 399 | } | 405 | } |
| 400 | 406 | ||
| 401 | // checkout branch | 407 | // checkout branch |
| 402 | if !self.get_checked_out_branch_name()?.eq(&branch_name) { | 408 | self.create_branch_at_commit(branch_name, &parent_commit_id)?; |
| 403 | self.create_branch_at_commit(branch_name, &parent_commit_id)?; | ||
| 404 | } | ||
| 405 | self.checkout(branch_name)?; | 409 | self.checkout(branch_name)?; |
| 406 | 410 | ||
| 407 | // apply commits | 411 | // apply commits |
| @@ -1940,4 +1944,97 @@ mod tests { | |||
| 1940 | } | 1944 | } |
| 1941 | } | 1945 | } |
| 1942 | } | 1946 | } |
| 1947 | mod ancestor_of { | ||
| 1948 | use super::*; | ||
| 1949 | |||
| 1950 | #[test] | ||
| 1951 | fn deep_ancestor_returns_true() -> Result<()> { | ||
| 1952 | let test_repo = GitTestRepo::default(); | ||
| 1953 | let from_main_in_feature_history = test_repo.populate()?; | ||
| 1954 | |||
| 1955 | // create feature branch and add 2 commits | ||
| 1956 | test_repo.create_branch("feature")?; | ||
| 1957 | |||
| 1958 | test_repo.checkout("feature")?; | ||
| 1959 | std::fs::write(test_repo.dir.join("t3.md"), "some content")?; | ||
| 1960 | test_repo.stage_and_commit("add t3.md")?; | ||
| 1961 | std::fs::write(test_repo.dir.join("t4.md"), "some content")?; | ||
| 1962 | let ahead_2_oid = test_repo.stage_and_commit("add t4.md")?; | ||
| 1963 | |||
| 1964 | let git_repo = Repo::from_path(&test_repo.dir)?; | ||
| 1965 | |||
| 1966 | assert!(git_repo.ancestor_of( | ||
| 1967 | &oid_to_sha1(&ahead_2_oid), | ||
| 1968 | &oid_to_sha1(&from_main_in_feature_history) | ||
| 1969 | )?); | ||
| 1970 | Ok(()) | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | #[test] | ||
| 1974 | fn commit_parent_returns_true() -> Result<()> { | ||
| 1975 | let test_repo = GitTestRepo::default(); | ||
| 1976 | test_repo.populate()?; | ||
| 1977 | |||
| 1978 | // create feature branch and add 2 commits | ||
| 1979 | test_repo.create_branch("feature")?; | ||
| 1980 | |||
| 1981 | test_repo.checkout("feature")?; | ||
| 1982 | std::fs::write(test_repo.dir.join("t3.md"), "some content")?; | ||
| 1983 | let ahead_1_oid = test_repo.stage_and_commit("add t3.md")?; | ||
| 1984 | std::fs::write(test_repo.dir.join("t4.md"), "some content")?; | ||
| 1985 | let ahead_2_oid = test_repo.stage_and_commit("add t4.md")?; | ||
| 1986 | |||
| 1987 | let git_repo = Repo::from_path(&test_repo.dir)?; | ||
| 1988 | |||
| 1989 | assert!(git_repo.ancestor_of(&oid_to_sha1(&ahead_2_oid), &oid_to_sha1(&ahead_1_oid))?); | ||
| 1990 | Ok(()) | ||
| 1991 | } | ||
| 1992 | |||
| 1993 | #[test] | ||
| 1994 | fn same_commit_returns_false() -> Result<()> { | ||
| 1995 | let test_repo = GitTestRepo::default(); | ||
| 1996 | test_repo.populate()?; | ||
| 1997 | |||
| 1998 | // create feature branch and add 2 commits | ||
| 1999 | test_repo.create_branch("feature")?; | ||
| 2000 | |||
| 2001 | test_repo.checkout("feature")?; | ||
| 2002 | std::fs::write(test_repo.dir.join("t3.md"), "some content")?; | ||
| 2003 | test_repo.stage_and_commit("add t3.md")?; | ||
| 2004 | std::fs::write(test_repo.dir.join("t4.md"), "some content")?; | ||
| 2005 | let ahead_2_oid = test_repo.stage_and_commit("add t4.md")?; | ||
| 2006 | |||
| 2007 | let git_repo = Repo::from_path(&test_repo.dir)?; | ||
| 2008 | |||
| 2009 | assert!(!git_repo.ancestor_of(&oid_to_sha1(&ahead_2_oid), &oid_to_sha1(&ahead_2_oid))?); | ||
| 2010 | Ok(()) | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | #[test] | ||
| 2014 | fn commit_not_in_history_returns_false() -> Result<()> { | ||
| 2015 | let test_repo = GitTestRepo::default(); | ||
| 2016 | test_repo.populate()?; | ||
| 2017 | |||
| 2018 | // create feature branch and add 2 commits | ||
| 2019 | test_repo.create_branch("feature")?; | ||
| 2020 | |||
| 2021 | // create commit not in feature history | ||
| 2022 | std::fs::write(test_repo.dir.join("notfeature.md"), "some content")?; | ||
| 2023 | let on_main_after_feature = test_repo.stage_and_commit("add notfeature.md")?; | ||
| 2024 | |||
| 2025 | test_repo.checkout("feature")?; | ||
| 2026 | std::fs::write(test_repo.dir.join("t3.md"), "some content")?; | ||
| 2027 | test_repo.stage_and_commit("add t3.md")?; | ||
| 2028 | std::fs::write(test_repo.dir.join("t4.md"), "some content")?; | ||
| 2029 | let ahead_2_oid = test_repo.stage_and_commit("add t4.md")?; | ||
| 2030 | |||
| 2031 | let git_repo = Repo::from_path(&test_repo.dir)?; | ||
| 2032 | |||
| 2033 | assert!(!git_repo.ancestor_of( | ||
| 2034 | &oid_to_sha1(&ahead_2_oid), | ||
| 2035 | &oid_to_sha1(&on_main_after_feature) | ||
| 2036 | )?); | ||
| 2037 | Ok(()) | ||
| 2038 | } | ||
| 2039 | } | ||
| 1943 | } | 2040 | } |