o EcE@sddlZddlZddlZddlZddlZddlZddlm Z m Z m Z ddl m Z mZddlmZmZmZddlmZddlmZmZmZmZmZmZmZejjZejjZe e!Z"e#dZ$e#dZ%e#d ej&Z'd e(d e)fd d Z*GdddeZ+e,e+dS)N)ListOptionalTuple) BadCommandInstallationError) HiddenText display_pathhide_url) make_command)AuthInfoRemoteNotFoundErrorRemoteNotValidError RevOptionsVersionControl(find_path_to_project_root_from_repo_rootvcsz(^git version (\d+)\.(\d+)(?:\.(\d+))?.*$z^[a-fA-F0-9]{40}$a/^ # Optional user, e.g. 'git@' (\w+@)? # Server, e.g. 'github.com'. ([^/:]+): # The server-side path. e.g. 'user/project.git'. Must start with an # alphanumeric character so as not to be confusable with a Windows paths # like 'C:/foo/bar' or 'C:\foo\bar'. (\w[^:]*) $shareturncCstt|SN)bool HASH_REGEXmatch)rrH/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/vcs/git.pylooks_like_hash7src sDeZdZdZdZdZdZdZdZe de de e fd d Z d e d e de fd dZdeedffddZede dee fddZed e de deee e ffddZed e de de fddZed e d ededefddZed e dee de fddZd e d ededdfd d!Zd e d ededdfd"d#Zd e d ededdfd$d%Zede de fd&d'Ze d e de fd(d)Zede de de fd*d+Z ed9de dee de fd,d-Z!ede dee fd.d/Z"ed e dee ee e#fffd0d1 Z$ede ddfd2d3Z%ede dee ffd4d5 Z&e d6e de fd7d8Z'Z(S):Gitgitz.gitclone)zgit+httpz git+httpszgit+sshzgit+gitzgit+file)ZGIT_DIRZ GIT_WORK_TREEHEADrevrcCs|gSrrrrrrget_base_rev_argsKszGit.get_base_rev_argsurldestcCsJ|t|\}}|jsdS|||jsdSt|||jd}| S)NFr)Zget_url_rev_optionsr ris_commit_id_equalrget_revision_sha)selfr"r#_ rev_optionsZis_tag_or_branchrrris_immutable_rev_checkoutOszGit.is_immutable_rev_checkout.cCsF|jdgddd}t|}|std|dStdd|DS) NversionFT) show_stdout stdout_onlyzCan't parse git version: %srcss|]}t|VqdSr)int).0crrr csz&Git.get_git_version..) run_commandGIT_VERSION_REGEXrloggerwarningtuplegroups)r&r*rrrrget_git_version]s   zGit.get_git_versionlocationcCsBgd}|j|ddd|d}|}|dr|tddSdS)zl Return the current branch, or None if HEAD isn't at a branch (e.g. detached HEAD). )z symbolic-ref-qrFTZextra_ok_returncodesr+r,cwdz refs/heads/N)r1strip startswithlen)clsr8argsoutputrefrrrget_current_branches  zGit.get_current_branchc Cs|jd|g|dddd}i}|dD](}|d}|sqz |jdd d \}}Wnty8td |w|||<qd |}d |} ||} | durU| dfS|| } | dfS)z Return (sha_or_none, is_branch), where sha_or_none is a commit hash if the revision names a remote branch or tag, otherwise None. Args: dest: the repository directory. rev: the revision name. zshow-refFTignore)r=r+r, on_returncode   )maxsplitzunexpected show-ref line: zrefs/remotes/origin/z refs/tags/N)r1r>splitrstrip ValueErrorget) rAr#rrCZrefslineZref_shaZref_nameZ branch_refZtag_refrrrrr%~s2        zGit.get_revision_shacCs.|drdSt|s dS|||rdSdS)a$ Return true if rev is a ref or is a commit that we don't have locally. Branches and tags are not considered in this method because they are assumed to be always available locally (which is a normal outcome of ``git clone`` and ``git fetch --tags``). zrefs/TF)r?r has_commit)rAr#rrrr _should_fetchs  zGit._should_fetchr(cCs|j}|||\}}|dur ||}|r||_|Sd|_|St|s*td||||s2|S|jt dd|| |d|j |dd}||}|S)z Resolve a revision to a new RevOptions object with the SHA1 of the branch, tag, or ref if found. Args: rev_options: a RevOptions object. Nz:Did not find branch or tag '%s', assuming revision or ref.fetchr9r=Z FETCH_HEADr ) Zarg_revr%make_new branch_namerr3r4rSr1r to_args get_revision)rAr#r"r(rrZ is_branchrrrresolve_revisions,     zGit.resolve_revisionnamecCs|sdS|||kS)z Return whether the current commit hash equals the given name. Args: dest: the repository directory. name: a string name. F)rY)rAr#r[rrrr$s zGit.is_commit_id_equalNc Cs |}td||t||dkr |tddd||n |tdd|||jrw||||}t |dd}t d|||dur\| ||js[tdd| }|j||d n%| ||krvd |}dd |d |g}|j||d n ||}||}td ||j||dS)NzCloning %s%s to %s)rKrz--filter=blob:noner9rWzRev options %s, branch_name %scheckoutrUzorigin/z-bz--trackzResolved %s to commit %s)Z to_displayr3inforr7r1r rrZgetattrdebugr$rXrErYrVupdate_submodules) r&r#r"r(Z rev_displayrWcmd_argsZ track_branchrrrr fetch_newsP      z Git.fetch_newcCsB|jtdd||dtdd|}|j||d||dS)Nconfigzremote.origin.urlrUr]r9)r1r rXrar&r#r"r(rbrrrswitch7s z Git.switchcCsn|dkr|jgd|dn |jddg|d||||}tddd|}|j||d||dS)N)r; )rTr9z--tagsrUrTr9resetz--hard)r7r1rZr rXrarerrrupdateAs z Git.updatecCsx|jgdddd|d}|}z|d}Wn tytw|D] }|dr-|}nq"|dd }||S) z Return URL of the first remote encountered. Raises RemoteNotFoundError if the repository does not have a remote url configured. )rdz --get-regexpzremote\..*\.urlr:FTr<rzremote.origin.url rJr;)r1 splitlines IndexErrorr r?rM_git_remote_to_pip_urlr>)rAr8stdoutZremotesZ found_remoteZremoter"rrrget_remote_urlOs(    zGit.get_remote_urlcCsJtd|r|Stj|rt|St|}|r!| dSt |)a8 Convert a remote url from what git uses to what pip accepts. There are 3 legal forms **url** may take: 1. A fully qualified url: ssh://git@example.com/foo/bar.git 2. A local project.git folder: /path/to/bare/repository.git 3. SCP shorthand for form 1: git@example.com:foo/bar.git Form 1 is output as-is. Form 2 must be converted to URI and form 3 must be converted to form 1. See the corresponding test test_git_remote_url_to_pip() for examples of sample inputs/outputs. z\w+://z ssh://\1\2/\3) rerospathexistspathlibPurePathas_uri SCP_REGEXexpandr )r"Z scp_matchrrrrlms    zGit._git_remote_to_pip_urlcCs8z|jdddd|g|ddWdStyYdSw)zU Check if rev is a commit that is available in the local repository. rev-parser9z--verifyzsha^F)r=log_failed_cmdT)r1r)rAr8rrrrrRs zGit.has_commitcCs*|durd}|jd|gdd|d}|S)NrrxFTr+r,r=)r1r>)rAr8rZ current_revrrrrYszGit.get_revisioncCsT|jddgdd|d}tj|stj||}tjtj|d}t||S)z Return the path to Python project root, relative to the repo root. Return None if the project root is in the repo root. rxz --git-dirFTrzz..)r1r>rprqisabsjoinabspathr)rAr8Zgit_dirZ repo_rootrrrget_subdirectorys  zGit.get_subdirectoryc st|\}}}}}|drC|dt|d }|tj|ddd}|dd} |d| t || d||||f}d|vr]|dd }t |\}} } |d d }n t |\}} } || | fS) a9 Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. That's required because although they use SSH they sometimes don't work with a ssh:// scheme (e.g. GitHub). But we need a scheme for parsing. Hence we remove it again afterwards and return it as a stub. fileN/\+r;z://zgit+z git+ssh://zssh://) urlsplitendswithr@lstripurllibZrequestZ url2pathnamereplacefind urlunsplitsuperget_url_rev_and_auth) rAr"schemenetlocrqqueryfragmentinitial_slashesnewpathZ after_plusrZ user_pass __class__rrrs$    zGit.get_url_rev_and_authcCs0tjtj|ds dS|jgd|ddS)Nz .gitmodules)Z submoduleriz--initz --recursiver9rU)rprqrrr|r1)rAr8rrrras  zGit.update_submodulescsxt|}|r |Sz|jddg|ddddd}Wnty)td|YdSty2YdSwtj | dS) Nrxz--show-toplevelFTraise)r=r+r,rGryzKcould not determine if %s is under git control because git is not availablez ) rget_repository_rootr1rr3r`rrprqnormpathrN)rAr8Zlocrrrrrs,   zGit.get_repository_rootrepo_urlcCsdS)zEIn either https or ssh form, requirements must be prefixed with git+.Tr)rrrrshould_add_vcs_url_prefixszGit.should_add_vcs_url_prefixr))__name__ __module__ __qualname__r[dirnameZ repo_nameZschemesZ unset_environZdefault_arg_rev staticmethodstrrr!rr)rr-r7 classmethodrrEr%rSrrrZr$rcrfrirnrlrRrYr~r rrarr __classcell__rrrrr;sd $- -7  &r)-ZloggingZos.pathrprsro urllib.parserZurllib.requesttypingrrrZpip._internal.exceptionsrrZpip._internal.utils.miscrrr Zpip._internal.utils.subprocessr Z pip._internal.vcs.versioncontrolr r r rrrrparserrZ getLoggerrr3compiler2rVERBOSErvrrrrregisterrrrrs8 $    I