U jaE@sddlZddlZddlZddlZddlZddlZddlm Z m Z m Z ddl m Z mZddlmZmZmZddlmZddlmZmZmZmZmZmZmZejjZejjZe e!Z"e#dZ$e#dZ%e#d ej&Z'd d Z(Gd d d eZ)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[^:]*) $cCstt|SN)bool HASH_REGEXmatch)sharm/private/var/folders/k6/_7fsz4ts3b78x3b3xwrxjh_c8s8xv7/T/pip-unpacked-wheel-bug3gbve/pip/_internal/vcs/git.pylooks_like_hash4srcseZdZdZdZdZdZdZdZe ddZ d d Z e e d fd d dZeddZeddZeddZeddZeddZddZddZddZedd Ze d!d"Zed#d$Zed2d&d'Zed(d)Zefd*d+Zed,d-Zefd.d/Ze d0d1Z Z!S)3Gitgitz.gitclone)zgit+httpz git+httpszgit+sshzgit+gitzgit+file)GIT_DIR GIT_WORK_TREEHEADcCs|gSrrrevrrrget_base_rev_argsEszGit.get_base_rev_argscCsJ|t|\}}|jsdS|||js.dSt|||jd}| S)NFr)get_url_rev_optionsr r!is_commit_id_equalrget_revision_sha)selfurldest_ rev_optionsis_tag_or_branchrrris_immutable_rev_checkoutJszGit.is_immutable_rev_checkout.)returncCs:|jdgddd}t|}|s$dStdd|DS)NversionFT) show_stdout stdout_onlyrcss|]}t|VqdSr)int).0crrr bsz&Git.get_git_version..) run_commandGIT_VERSION_REGEXrtuplegroups)r&r.rrrrget_git_version[s zGit.get_git_versioncCsDdddg}|j|ddd|d}|}|dr@|tdd Sd S) zl Return the current branch, or None if HEAD isn't at a branch (e.g. detached HEAD). z symbolic-ref-qrFTextra_ok_returncodesr/r0cwdz refs/heads/N)r5strip startswithlen)clslocationargsoutputrefrrrget_current_branchds  zGit.get_current_branchc Cs|jd|g|dddd}i}|dD]V}|d}|s>q*z|jdd d \}}Wn"tk rvtd |YnX|||<q*d |}d |} ||} | dk r| 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/r0 on_returncode   )maxsplitzunexpected show-ref line: zrefs/remotes/origin/z refs/tags/N)r5r@splitrstrip ValueErrorget) rCr(r!rFrefslineZref_shaZref_name branch_reftag_refrrrrr%~s0       zGit.get_revision_shacCs.|drdSt|sdS|||r*dSdS)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)rAr has_commit)rCr(r!rrr _should_fetchs  zGit._should_fetchcCs|j}|dk st|||\}}|dk rF||}|r<|nd|_|St|sZtd||||sj|S|j t 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.fetchr:r? FETCH_HEADr ) arg_revAssertionErrorr%make_new branch_namerloggerwarningrYr5r to_args get_revision)rCr(r'r*r!r is_branchrrrresolve_revisions*     zGit.resolve_revisioncCs|sdS|||kS)z Return whether the current commit hash equals the given name. Args: dest: the repository directory. name: a string name. F)rd)rCr(namerrrr$s zGit.is_commit_id_equalc Cs|}td||t||tdd|||jr||||}t|dd}|dkr| ||jstdd| }|j||dq| ||krd|}dd|d |g}|j||dn| |}| |}td ||j||dS) NzCloning %s%s to %srr:r`checkoutr[zorigin/z-bz--trackzResolved %s to commit %s) to_displayrainforr5r r!rfgetattrr$rcrHrdr_update_submodules) r&r(r'r* rev_displayr`cmd_args track_branchrrrr fetch_news6    z Git.fetch_newcCsB|jtdd||dtdd|}|j||d||dS)Nconfigzremote.origin.urlr[rhr:)r5r rcrlr&r(r'r*rnrrrswitch%s z Git.switchcCsp|dkr"|jdddg|dn|jddg|d||||}tddd|}|j||d||dS)N)r< rZr:z--tagsr[resetz--hard)r9r5rfr rcrlrrrrrupdate0s z Git.updatecCs|jdddgddd|d}|}z |d}Wntk rFtYnX|D]}|d rL|}qdqL|d d }||S) z Return URL of the first remote encountered. Raises RemoteNotFoundError if the repository does not have a remote url configured. rqz --get-regexpzremote\..*\.urlr;FTr=rzremote.origin.url rMr<)r5 splitlines IndexErrorr rArP_git_remote_to_pip_urlr@)rCrDstdoutremotes found_remoteremoter'rrrget_remote_url?s$    zGit.get_remote_urlcCsNtd|r|Stj|r*t|St|}|rB| dSt |dS)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/\3N) rerospathexistspathlibPurePathas_uri SCP_REGEXexpandr )r'Z scp_matchrrrry^s    zGit._git_remote_to_pip_urlcCs@z |jdddd|g|ddWntk r6YdSXdSdS) zU Check if rev is a commit that is available in the local repository. rev-parser:z--verifyzsha^F)r?log_failed_cmdTN)r5r)rCrDr!rrrrX~s zGit.has_commitNcCs*|dkr d}|jd|gdd|d}|S)NrrFTr/r0r?)r5r@)rCrDr! current_revrrrrdszGit.get_revisioncCsT|jddgdd|d}tj|s4tj||}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. rz --git-dirFTrz..)r5r@rrisabsjoinabspathr)rCrDgit_dir repo_rootrrrget_subdirectorys  zGit.get_subdirectoryc st|\}}}}}|dr|dt|d }|tj|ddd}|dd} |d| t || d||||f}d|krd|kst |d d }t |\}} } |d d }nt |\}} } || | 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://zfile:zgit+z git+ssh://zssh://) urlsplitendswithrBlstripurllibrequest url2pathnamereplacefind urlunsplitr^superget_url_rev_and_auth) rCr'schemenetlocrqueryfragmentinitial_slashesnewpath after_plusr! user_pass __class__rrrs.      zGit.get_url_rev_and_authcCs6tjtj|dsdS|jdddddg|ddS)Nz .gitmodules submodulervz--initz --recursiver:r[)rrrrr5)rCrDrrrrls  zGit.update_submodulescs|t|}|r|Sz|jddg|ddddd}Wn6tk rTtd|YdStk rhYdSXtj | dS) Nrz--show-toplevelFTraise)r?r/r0rJrzKcould not determine if %s is under git control because git is not availablez ) rget_repository_rootr5rradebugrrrnormpathrQ)rCrDlocrrrrrs(  zGit.get_repository_rootcCsdS)zNIn either https or ssh form, requirements must be prefixed with git+. Tr)repo_urlrrrshould_add_vcs_url_prefixszGit.should_add_vcs_url_prefix)N)"__name__ __module__ __qualname__rgdirname repo_nameschemes unset_environdefault_arg_rev staticmethodr"r,rr1r9 classmethodrHr%rYrfr$rprsrvr~ryrXrdrrrlrr __classcell__rrrrr9sR    .  , #      ! r)+loggingos.pathrrr urllib.parserurllib.requesttypingrrrpip._internal.exceptionsrrpip._internal.utils.miscrrr pip._internal.utils.subprocessr pip._internal.vcs.versioncontrolr r r rrrrparserr getLoggerrracompiler6rVERBOSErrrregisterrrrrs4 $     D