async def clone_git(clonespec): """Note: we ignore transforming git submodules into fat repository here since we'll rewrite history for the branch if we do that""" with asutil.TemporaryDirectory(suffix="git") as clone_dir: c = await config.get_configuration() git_user = c.get("git_username") new_internal_repo = await check_new_internal_repo( asutil.add_username_url(clonespec["targetRepoUrl"], git_user) ) logger.info( "The internal repository considered new? => " + str(new_internal_repo) ) # NCL-4255: if ref provided and internal repository is not 'new', sync the ref only if "ref" in clonespec and clonespec["ref"] and not new_internal_repo: await git.clone(clone_dir, clonespec["originRepoUrl"]) # Clone origin await git.checkout(clone_dir, clonespec["ref"], force=True) # Checkout ref await git.add_remote( clone_dir, "target", asutil.add_username_url(clonespec["targetRepoUrl"], git_user), ) # Add target remote ref = clonespec["ref"] await push_sync_changes(clone_dir, ref, "target") else: # Sync everything if ref not specified or internal repository is new # From: https://stackoverflow.com/a/7216269/2907906 logger.info("Syncing everything") await git.clone_mirror( clone_dir + "/.git", clonespec["originRepoUrl"] ) # Clone origin await git.disable_bare_repository(clone_dir) await git.reset_hard(clone_dir) await git.add_remote( clone_dir, "target", asutil.add_username_url(clonespec["targetRepoUrl"], git_user), ) # Add target remote await git.push_all(clone_dir, "target", tags_also=True) return clonespec
async def adjust(adjustspec, repo_provider): """ This method executes adjust providers as specified in configuration. Returns a dictionary corresponding to the HTTP response content. """ c = await config.get_configuration() adjust_result = {"adjustType": [], "resultData": {}} result = {} verify_only_authorized_urls_used(adjustspec, c) # By default the buildType is Maven build_type = "MVN" if "buildType" in adjustspec: logger.info("Build Type specified: " + adjustspec["buildType"]) build_type = adjustspec["buildType"] with asutil.TemporaryDirectory(suffix="git") as work_dir: repo_url = await repo_provider(adjustspec, create=False) process_mdc("BEGIN", "SCM_CLONE") sync_enabled = await is_sync_on(adjustspec) if sync_enabled: await sync_external_repo(adjustspec, repo_provider, work_dir, c) else: git_user = c.get("git_username") await git.clone(work_dir, asutil.add_username_url(repo_url.readwrite, git_user)) # Clone origin await git.checkout(work_dir, adjustspec["ref"], force=True) # Checkout ref await asgit.setup_commiter(expect_ok, work_dir) await asgit.transform_git_submodule_into_fat_repository(work_dir) process_mdc("END", "SCM_CLONE") process_mdc("BEGIN", "ALIGNMENT_ADJUST") ### Adjust Phase ### if build_type == "MVN": specific_tag_name = await adjust_mvn(work_dir, c, adjustspec, adjust_result) elif build_type == "GRADLE": specific_tag_name = await adjust_gradle(work_dir, c, adjustspec, adjust_result) elif build_type == "SBT": specific_tag_name = await adjust_scala(work_dir, c, adjustspec, adjust_result) else: specific_tag_name = await adjust_project_manip( work_dir, c, adjustspec, adjust_result) is_pull_request = git.is_ref_a_pull_request(adjustspec["ref"]) # if we are aligning from a PR, indicate it as such in the tag name if is_pull_request: specific_tag_name = "Pull_Request-" + specific_tag_name result = await commit_adjustments( repo_dir=work_dir, repo_url=repo_url, original_ref=adjustspec["ref"], adjust_type=", ".join(adjust_result["adjustType"]), force_continue_on_no_changes=True, specific_tag_name=specific_tag_name, ) result = result if result is not None else {} result["adjustResultData"] = adjust_result["resultData"] process_mdc("END", "ALIGNMENT_ADJUST") return result
async def sync_external_repo(adjustspec, repo_provider, work_dir, configuration): """Get external repository and its ref into the internal repository""" internal_repo_url = await repo_provider(adjustspec, create=False) git_user = configuration.get("git_username") await git.clone(work_dir, adjustspec["originRepoUrl"]) # Clone origin # See NCL-4069: sometimes even with sync on, the upstream repo might not have the ref, but the downstream repo will # if ref exists on upstream repository, continue the sync as usual # if no, make sure ref exists on downstream repository, and checkout the correct repo # if no, then fail completely ref_exists = await check_ref_exists(work_dir, adjustspec["ref"]) if ref_exists: is_pull_request = git.is_ref_a_pull_request(adjustspec["ref"]) if is_pull_request: await git.checkout_pr(work_dir, adjustspec["ref"]) else: await git.checkout(work_dir, adjustspec["ref"], force=True) # Checkout ref await git.rename_remote(work_dir, "origin", "origin_remote") # Rename origin remote await git.add_remote( work_dir, "origin", asutil.add_username_url(internal_repo_url.readwrite, git_user), ) # Add target remote ref = adjustspec["ref"] # Sync if is_pull_request: logger.info( "Syncing of Pull Request to downstream repository disabled since the ref is a pull request" ) else: await clone.push_sync_changes(work_dir, ref, "origin", origin_remote="origin_remote") else: logger.warn( "Upstream repository does not have the 'ref'. Trying to see if 'ref' present in downstream repository" ) # Delete the upstreamed clone repository shutil.rmtree(work_dir) os.makedirs(work_dir) # Clone the internal repository await git.clone(work_dir, asutil.add_username_url(internal_repo_url.readwrite, git_user)) # Clone origin ref_exists = await check_ref_exists(work_dir, adjustspec["ref"]) if ref_exists: logger.info( "Downstream repository has the ref, but not the upstream one. No syncing required!" ) await git.checkout(work_dir, adjustspec["ref"], force=True) # Checkout ref else: logger.error( "Both upstream and downstream repository do not have the 'ref' present. Cannot proceed" ) raise exception.AdjustCommandError( "Both upstream and downstream repository do not have the 'ref' present. Cannot proceed", [], exit_code=10, ) # At this point the target repository might have the ref we want to sync, but the local repository might not have all the tags # from the target repository. We need to sync tags because we use it to know if we have tags with existing changes or if we # need to create tags of format <version>-<sha> if existing tag with name <version> exists after pme changes await git.fetch_tags(work_dir, remote="origin")