diff --git a/hooks/first_parent.py b/hooks/first_parent.py index 2a38af340ef2215e0aef841d627cedd7b7952c89..edf8b8ed65343c4e7cbea99012c267a778c7bc93 100755 --- a/hooks/first_parent.py +++ b/hooks/first_parent.py @@ -74,10 +74,26 @@ def resolve_ref(ref: str) -> Optional[str]: return proc.stdout.strip() or None +def is_ancestor(head_ref: str, other_ref: str) -> bool: + """ + Return True if "other_ref" is an ancestor of "head_ref" + + Note that "head_ref" refers to the head of a DAG graph to check, not a named reference + in the refs/heads/ namespace. + """ + cmd = ["git", "merge-base", "--is-ancestor", other_ref, head_ref] + return 0 == run(cmd).returncode + + def check(ref: str, upstream: str) -> None: """ Exit with 1 if "upstream" can reach first-parent commits not reachable from "ref" + + Skipped if "upstream" is not an ancestor of "ref". This would indicate rebasing which + should be checked separately. """ + if not is_ancestor(ref, upstream): + return head_commits = get_fp_commits(ref) upstream_commits = get_fp_commits(upstream) if not upstream_commits.difference(head_commits):