summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Chien <jeff@jemstep.com>2020-03-10 15:48:21 +0200
committerJeff Chien <jeff@jemstep.com>2020-03-10 15:48:21 +0200
commitd33944d252c630e6db20ffcb8b5d4e85d5ffcf75 (patch)
tree2350797740fffabae85e6c7e00f26996537e4fe0
parent371643f2810bf10b963feed0c9ad8405d3826677 (diff)
PYKE-11910: implemented working rebase logic
-rw-r--r--src/git.rs9
-rw-r--r--src/policies.rs17
-rw-r--r--tests/policies_test.rs26
3 files changed, 45 insertions, 7 deletions
diff --git a/src/git.rs b/src/git.rs
index 91902a3..7a0ffa8 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -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());
+}