import subprocess
__LONG_COMMIT_HASH_LENGTH: int = 40
def __validate_commit_hash(commit_hash: str) -> None:
if commit_hash == "" or len(commit_hash) != __LONG_COMMIT_HASH_LENGTH:
raise ValueError(f"Invalid commit hash: {commit_hash}")
def check_if_commit_is_valid(commit_hash: str) -> bool:
git_cmd: str = f"git rev-parse --quiet --verify {commit_hash}^{{commit}}"
bash_cmd: str = f"bash -l -c \'{git_cmd}\'"
process: subprocess.Popen = subprocess.Popen(
bash_cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
stdout: str = stdout.replace("\n", "")
return False if stdout == "" or stderr != "" else True
def get_head_commit(branch_name: str) -> str:
if branch_name == "":
raise ValueError("Expected non-empty branch name")
git_cmd: str = f"git show --format=%H -s {branch_name}"
bash_cmd: str = f"bash -l -c \'{git_cmd}\'"
process = subprocess.Popen(bash_cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
stdout: str = stdout.replace("\n", "")
if stdout == "":
raise ValueError(f"Expected non-empty output for {git_cmd}")
if stderr != "":
raise ValueError(f"Expected empty error for {git_cmd}, got {stderr}")
return stdout
def get_root_commit(branch_name: str) -> str:
if branch_name == "":
raise ValueError("Expected non-empty branch name")
git_cmd: str = f"git rev-list --date-order --max-parents=0 {branch_name} | tail -n 1"
bash_cmd: str = f"bash -l -c \'{git_cmd}\'"
process: subprocess.Popen = subprocess.Popen(
bash_cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
stdout: str = stdout.replace("\n", "")
if stdout == "":
raise ValueError(f"Expected non-empty output for {git_cmd}")
if stderr != "":
raise ValueError(f"Expected empty error for {git_cmd}, got {stderr}")
return stdout
def check_if_merge_commit(commit_hash: str) -> bool:
__validate_commit_hash(commit_hash)
git_command: str = f"git show --format=%P -s {commit_hash}"
bash_cmd: str = f"bash -l -c \'{git_command}\'"
process: subprocess.Popen = subprocess.Popen(
bash_cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, _ = process.communicate()
stdout: str = stdout.replace("\n", "")
return len(stdout.split()) > 1
def get_short_commit_hash(commit_hash: str) -> str:
__validate_commit_hash(commit_hash)
git_cmd: str = f"git rev-parse --short {commit_hash}"
bash_cmd: str = f"bash -l -c \'{git_cmd}\'"
process: subprocess.Popen = subprocess.Popen(
bash_cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
stdout: str = stdout.replace("\n", "")
if stdout == "":
raise ValueError(f"Expected non-empty output for {git_cmd}")
if stderr != "":
raise ValueError(f"Expected empty error for {git_cmd}, got {stderr}")
return stdout
def compute_commit_distance(base_commit_hash: str, head_commit_hash: str) -> int:
__validate_commit_hash(base_commit_hash)
__validate_commit_hash(head_commit_hash)
git_cmd: str = f"git rev-list --count {base_commit_hash}..{head_commit_hash}"
bash_cmd: str = f"bash -l -c \'{git_cmd}\'"
process: subprocess.Popen = subprocess.Popen(
bash_cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
stdout: str = stdout.replace("\n", "")
if stdout == "":
raise ValueError(f"Expected non-empty output for {git_cmd}")
if stderr != "":
raise ValueError(f"Expected empty error for {git_cmd}, got {stderr}")
return int(stdout)