def analyze_review_branch_tracking_situation(cli: CLIUX, repo: Repo, active_branch: Head): active_branch_tracked_ref = active_branch.tracking_branch() if (active_branch_tracked_ref is None): raise NonApplicableSituationException( f"Branch {active_branch.name} does not track a remote branch", "The currently active branch does not track a remote branch yet, perhaps you have not pushed it yet?" ) cli.info( f"""determined that local branch {format_branch_name(active_branch.name)} tracks upstream branch { format_branch_name(active_branch_tracked_ref.remote_head) } on remote {format_remote_name(active_branch_tracked_ref.remote_name)}""" ) with yaspin().white.bold as sp: sp.text = f"searching for new upstream commits on {active_branch_tracked_ref.name}" sp.start() latest_remote_sha = git_ls_remote(repo=repo, ref=active_branch_tracked_ref, ref_types=["heads"]) latest_local_sha = active_branch_tracked_ref.commit.hexsha sp.stop() cli.debug( f"latest commit for local ref {active_branch_tracked_ref.name}: {latest_local_sha}" ) cli.debug( f"""latest commit for tracked branch {active_branch_tracked_ref.remote_head } on remote {active_branch_tracked_ref.remote_name}: {latest_remote_sha}""" ) return (latest_remote_sha, active_branch_tracked_ref)
def offer_to_fetch_from_upstream(cli: CLIUX, repo: Repo, opts: ValidateOptions, active_branch: Head, active_branch_tracked_ref: RemoteReference): cli.warning(f"""New commits on {active_branch_tracked_ref } were detected, which have not yet been pulled down to {active_branch.name}""" ) determine_whether_to_auto_fetch(cli, opts, active_branch_tracked_ref) origin: Remote = repo.remotes['origin'] refspec = f"{active_branch.name}:{active_branch_tracked_ref.name}" cli.info( f"Fetching new commits for branch {active_branch_tracked_ref.name}") cli.debug( f"running 'git fetch' from remote '{origin.name}' with refspec '{refspec}'" ) origin.fetch() cli.info(f"Fetch from {origin.name} complete")
async def do_validate(cli: CLIUX, opts: ValidateOptions): try: cwd = opts.get_cwd() # working directory repo = Repo(cwd) # git repo validate_remotes(repo=repo) (active_branch, default_branch) = await validate_branches_and_merge_bases(cli=cli, repo=repo, opts=opts) (latest_remote_sha, active_branch_tracked_ref) = analyze_review_branch_tracking_situation( cli, repo, active_branch) has_latest_commits_from_upstream = git_does_commit_exist_locally( repo=repo, sha=latest_remote_sha) if (has_latest_commits_from_upstream == False): offer_to_fetch_from_upstream( cli=cli, repo=repo, opts=opts, active_branch=active_branch, active_branch_tracked_ref=active_branch_tracked_ref) cli.info( f"Comparing {active_branch.name} against {active_branch_tracked_ref.name}" ) merge_base = validate_merge_bases_with_default_branch( cli, repo, repo.active_branch.name, active_branch_tracked_ref.name) cli.debug(f"Identified common commit {merge_base.hexsha[0:8]}") cli.debug(f"Local sha: {active_branch.commit.hexsha}") cli.debug(f"Upstream sha: {active_branch_tracked_ref.commit.hexsha}") new_local_commits = get_truncated_log(repo, active_branch.commit, merge_base.hexsha) new_upstream_commits = get_truncated_log( repo, active_branch_tracked_ref.commit, merge_base.hexsha) cli.debug(f"new local commits: {new_local_commits}") cli.debug(f"new upstream commits: {new_upstream_commits}") if (len(new_local_commits) > opts.get_commit_count_hard_fail_threshold()): raise LikelyUserErrorException( "Very large number of review branch commits", f"""An very large {len(new_local_commits)} number of commits were detected on review branch { active_branch.name }, which were not found on tracked branch {active_branch_tracked_ref.name }. {format_highlight("This may be an indication of an improper rebase!")} This warning is presented whenever more than {format_integer(opts.get_commit_count_hard_fail_threshold()) } new commits that have not yet been pushed are found on a review branch. Please take a close look at your review branch, and ensure you don't see any duplicate commits that are already on { default_branch.name}""") elif (len(new_local_commits) > opts.get_commit_count_soft_fail_threshold()): raise UserBypassableWarning( "Large number of review branch commits", f"""An unusually large {format_integer(len(new_local_commits))} number of commits were detected on review branch { active_branch.name }, which were not found on tracked branch {active_branch_tracked_ref.name }. {format_highlight("This may be an indication of an improper rebase!")} This warning is presented whenever more than {opts.get_commit_count_soft_fail_threshold() } new commits, that have not yet been pushed, are found on a review branch. Please take a close look at your review branch, and ensure you don't see any duplicate commits that are already on { default_branch.name}""") except UserBypassException as ex: cli.handle_user_bypass_exception(ex) except UserBypassableWarning as ex: cli.handle_user_bypassable_warning( ex, bypass_response=("continue" if opts.should_auto_bypass_commit_count_soft_fail() else None)) except NonApplicableSituationException as ex: cli.handle_non_applicable_situation_exception(ex) except UnhandledSituationException as ex: cli.handle_unhandled_situation_exception(ex) except InvalidGitRepositoryError: cli.error( f"""git_guardrails is only intended for use within a git repository directory {cwd} does not seem to be a git repository""")