From d54f2b2f3ce73cca3d70e5e8f62b082704b83f77 Mon Sep 17 00:00:00 2001 From: Dom Sekotill Date: Mon, 2 May 2022 21:41:03 +0100 Subject: [PATCH] Make first_parent.py check refs specified by the env --- hooks/first_parent.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/hooks/first_parent.py b/hooks/first_parent.py index 158d1e2..2a38af3 100755 --- a/hooks/first_parent.py +++ b/hooks/first_parent.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2021 Dominik Sekotill +# Copyright 2021, 2022 Dominik Sekotill # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ first-parent graph (dubbed a "foxtrot merge") I suggest the following article: """ import sys +from os import environ from subprocess import PIPE from subprocess import CalledProcessError from subprocess import run @@ -73,18 +74,40 @@ def resolve_ref(ref: str) -> Optional[str]: return proc.stdout.strip() or None +def check(ref: str, upstream: str) -> None: + """ + Exit with 1 if "upstream" can reach first-parent commits not reachable from "ref" + """ + head_commits = get_fp_commits(ref) + upstream_commits = get_fp_commits(upstream) + if not upstream_commits.difference(head_commits): + return + sys.stderr.write(FAIL_MSG.format(upstream=upstream)) + sys.exit(1) + + def main() -> None: """ CLI entrypoint """ - if not resolve_ref('@{upstream}'): + remote_name = environ.get("PRE_COMMIT_REMOTE_NAME") + remote_head = environ.get("PRE_COMMIT_FROM_REF") + local_ref = environ.get("PRE_COMMIT_TO_REF") + + # If remote_head/local_ref is None just assume this is not running as a Pre-Commit hook + if remote_head is None or local_ref is None: + check("HEAD", "@{upstream}") return - head_commits = get_fp_commits('HEAD') - upstream_commits = get_fp_commits('@{upstream}') - if not upstream_commits.difference(head_commits): + + # If remote_name is not set this is definitely not the tracked upstream + if remote_name is None: return - sys.stderr.write(FAIL_MSG.format(upstream=resolve_ref('@{upstream}'))) - sys.exit(1) + + remote_head = f"{remote_name}/{remote_head}" + upstream = resolve_ref(f'{local_ref}@{{upstream}}') + + if upstream and upstream == resolve_ref(remote_head): + check(local_ref, upstream) if __name__ == '__main__': -- GitLab