diff options
author | Jeff Chien <jeff@jemstep.com> | 2020-03-10 15:48:21 +0200 |
---|---|---|
committer | Jeff Chien <jeff@jemstep.com> | 2020-03-10 15:48:21 +0200 |
commit | d33944d252c630e6db20ffcb8b5d4e85d5ffcf75 (patch) | |
tree | 2350797740fffabae85e6c7e00f26996537e4fe0 | |
parent | 371643f2810bf10b963feed0c9ad8405d3826677 (diff) |
PYKE-11910: implemented working rebase logic
-rw-r--r-- | src/git.rs | 9 | ||||
-rw-r--r-- | src/policies.rs | 17 | ||||
-rw-r--r-- | tests/policies_test.rs | 26 |
3 files changed, 45 insertions, 7 deletions
@@ -22,6 +22,7 @@ pub struct Commit { pub is_identical_tree_to_any_parent: bool, pub is_merge_commit: bool, pub tags: Vec<Tag>, + pub parents: Vec<Oid>, } #[derive(Debug, Clone)] @@ -72,6 +73,7 @@ pub trait Git: Sized { let config = Config::from_toml_string(&config_str)?; Ok(config) } + fn is_descendent_of(&self, commit: Oid, ancestor: Oid) -> Result<bool, Box<dyn Error>>; } pub struct LiveGit { @@ -170,6 +172,7 @@ impl Git for LiveGit { is_merge_commit: commit.parent_count() > 1, is_identical_tree_to_any_parent: Self::is_identical_tree_to_any_parent(&commit), tags: tags, + parents: commit.parent_ids().collect(), }) } @@ -390,6 +393,12 @@ impl Git for LiveGit { _ => false, } } + + fn is_descendent_of(&self, commit: Oid, ancestor: Oid) -> Result<bool, Box<dyn Error>> { + self.repo + .graph_descendant_of(commit, ancestor) + .map_err(|e| e.into()) + } } impl LiveGit { diff --git a/src/policies.rs b/src/policies.rs index 5930caf..2662f10 100644 --- a/src/policies.rs +++ b/src/policies.rs @@ -167,6 +167,7 @@ pub fn verify_git_commits<G: Git, P: Gpg>( old_commit_id, new_commit_id, ref_name, + &config.override_tag_pattern, )?); } } @@ -373,10 +374,12 @@ fn verify_rebased<G: Git>( old_commit_id: Oid, new_commit_id: Oid, ref_name: &str, + override_tag_pattern: &Option<String>, ) -> Result<PolicyResult, Box<dyn Error>> { let new_branch = old_commit_id.is_zero(); let is_merge = git.is_merge_commit(new_commit_id); let is_mainline = git.is_mainline(ref_name)?; + let new_commit = git.find_commit(new_commit_id, override_tag_pattern)?; if !is_mainline { info!( @@ -400,10 +403,18 @@ fn verify_rebased<G: Git>( ); Ok(PolicyResult::Ok) } else { - let new_commit_is_identical_tree_to_parent = commits + let new_commit_is_rebased = new_commit + .parents + .iter() + .map(|parent_id| { + git.is_descendent_of(*parent_id, old_commit_id) + .map(|is_descendent| is_descendent || *parent_id == old_commit_id) + }) + .collect::<Result<Vec<bool>, _>>()? .iter() - .any(|commit| commit.id == new_commit_id && commit.is_identical_tree_to_any_parent); - if new_commit_is_identical_tree_to_parent { + .all(|x| *x); + + if new_commit_is_rebased { info!( "Rebase verification passed for {}: Branch is up to date with the mainline it's being merged into", new_commit_id diff --git a/tests/policies_test.rs b/tests/policies_test.rs index eeecc52..e12faf8 100644 --- a/tests/policies_test.rs +++ b/tests/policies_test.rs @@ -268,7 +268,7 @@ fn verify_git_commits_author_merged_own_code_on_configured_mainline() { &LiveGit::new( "./", GitConfig { - mainlines: vec!["m*".into()], + mainlines: vec!["master".into()], }, ) .unwrap(), @@ -376,7 +376,7 @@ fn verify_unrebased_branch_is_allowed_if_not_required() { verify_rebased: false, ..verify_commits_config() }, - "7f9763e189ade34345e683ab7e0c22d164280452", + "eb5e0185546b0bb1a13feec6b9ee8b39985fea42", "6eea56095f7498043f1d3d74bad46056b92675ea", "refs/heads/master", ) @@ -394,7 +394,7 @@ fn verify_unrebased_branch_is_blocked_if_required() { verify_rebased: true, ..verify_commits_config() }, - "7f9763e189ade34345e683ab7e0c22d164280452", + "eb5e0185546b0bb1a13feec6b9ee8b39985fea42", "6eea56095f7498043f1d3d74bad46056b92675ea", "refs/heads/master", ) @@ -418,4 +418,22 @@ fn verify_rebased_branch_is_allowed_when_required() { ) .unwrap(); assert!(result.is_ok(), "Error: {:?}", result); -}
\ No newline at end of file +} + +#[test] +fn verify_unrebased_branch_is_blocked_when_mainline_has_reverts() { + before_all(); + let result = policies::verify_git_commits::<LiveGit, MockGpg>( + &LiveGit::default("./").unwrap(), + MockGpg, + &VerifyGitCommitsConfig { + verify_rebased: true, + ..verify_commits_config() + }, + "3f48e07e5f8d5ab932a0a298ba3dd52809eef6d2", + "3911fdcbba1621d39096cef1bddbf4b35be2aeb6", + "refs/heads/master", + ) + .unwrap(); + assert!(result.is_err()); +} |