o
    ©„jIK  ã                   @  s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dl	m
Z
 d dlmZ d dlmZmZ d dlmZmZmZmZ d dlmZ d dlmZmZmZmZmZmZmZ ejj Z ejj!Z!e "e#¡Z$e %d	¡Z&e %d
¡Z'e %dej(¡Z)ddd„Z*G dd„ deƒZ+e ,e+¡ dS )é    )ÚannotationsN)Úreplace)ÚAny)Ú
BadCommandÚInstallationError)Ú
HiddenTextÚdisplay_pathÚhide_urlÚ	strtobool)Úmake_command)ÚAuthInfoÚRemoteNotFoundErrorÚRemoteNotValidErrorÚ
RevOptionsÚVersionControlÚ(find_path_to_project_root_from_repo_rootÚvcsz(^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[^:]*)
    $ÚshaÚstrÚreturnÚboolc                 C  s   t t | ¡ƒS ©N)r   Ú
HASH_REGEXÚmatch)r   © r   úS/var/www/html/django_cbt/venv/lib/python3.10/site-packages/pip/_internal/vcs/git.pyÚlooks_like_hash9   s   r   c                      sR  e Zd ZdZdZdZdZdZdZe	dJdd„ƒZ
edK‡ fdd„ƒZdLdd„ZdMdd„ZedNdd„ƒZedOdd „ƒZedPd!d"„ƒZedQd&d'„ƒZedRd)d*„ƒZdSd.d/„Z	0dTdSd1d2„Z	0dTdSd3d4„ZedUd5d6„ƒZe	dVd7d8„ƒZedWd9d:„ƒZedXdYd<d=„ƒZedNd>d?„ƒZedZ‡ fdAdB„ƒZedTd[dCdD„ƒZedN‡ fdEdF„ƒZe	d\dHdI„ƒZ‡  Z S )]ÚGitÚgitz.gitÚclone)zgit+httpz	git+httpszgit+sshzgit+gitzgit+file)ÚGIT_DIRÚGIT_WORK_TREEÚHEADÚrevr   r   ú	list[str]c                 C  s   | gS r   r   ©r#   r   r   r   Úget_base_rev_argsM   s   zGit.get_base_rev_argsÚargsr   Úkwargsc                   sB   t j d¡r| di ¡}d|d< d|d< ||d< tƒ j|i |¤ŽS )NÚPIP_NO_INPUTÚextra_environÚ0ÚGIT_TERMINAL_PROMPTzssh -oBatchMode=yesÚGIT_SSH_COMMAND)ÚosÚenvironÚgetÚsuperÚrun_command)Úclsr'   r(   r*   ©Ú	__class__r   r   r2   Q   s   zGit.run_commandÚurlÚdestr   c                 C  sJ   |   t|ƒ¡\}}|jsdS |  ||j¡sdS t|  ||j¡d ƒ}| S )NFr   )Úget_url_rev_optionsr	   r#   Úis_commit_id_equalr   Úget_revision_sha)Úselfr6   r7   Ú_Úrev_optionsÚis_tag_or_branchr   r   r   Úis_immutable_rev_checkoutZ   s   zGit.is_immutable_rev_checkoutútuple[int, ...]c                 C  sN   | j dgdddd�}t |¡}|st d|¡ dS t| d¡ƒt| d	¡ƒfS )
NÚversionzgit versionFT)Úcommand_descÚshow_stdoutÚstdout_onlyzCan't parse git version: %sr   é   é   )r2   ÚGIT_VERSION_REGEXr   ÚloggerÚwarningÚintÚgroup)r;   rA   r   r   r   r   Úget_git_versionh   s   ü
zGit.get_git_versionÚlocationú
str | Nonec                 C  sB   g d¢}| j |ddd|d�}| ¡ }| d¡r|tdƒd… S dS )zl
        Return the current branch, or None if HEAD isn't at a branch
        (e.g. detached HEAD).
        )zsymbolic-refú-qr"   ©rE   FT©Úextra_ok_returncodesrC   rD   Úcwdzrefs/heads/N)r2   ÚstripÚ
startswithÚlen)r3   rM   r'   ÚoutputÚrefr   r   r   Úget_current_branchu   s   
û
zGit.get_current_branchútuple[str | None, bool]c              	   C  s¼   | j d|g|dddd�}i }| ¡  d¡D ](}| d¡}|sqz|jdd	d
�\}}W n ty8   td|›�ƒ‚w |||< qd|› �}d|› �}	| |¡}
|
durU|
dfS | |	¡}
|
dfS )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.
        zshow-refFTÚignore)rS   rC   rD   Úon_returncodeÚ
úú rF   )Úmaxsplitzunexpected show-ref line: zrefs/remotes/origin/z
refs/tags/N)r2   rT   ÚsplitÚrstripÚ
ValueErrorr0   )r3   r7   r#   rW   ÚrefsÚlineÚref_shaÚref_nameÚ
branch_refÚtag_refr   r   r   r   r:   Ž   s2   û
ý




zGit.get_revision_shac                 C  s.   |  d¡rdS t|ƒsdS |  ||¡rdS dS )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``).
        zrefs/TF)rU   r   Ú
has_commit)r3   r7   r#   r   r   r   Ú_should_fetch¼   s   
	zGit._should_fetchr   r=   r   c                 C  s¨   |j }|dus	J ‚|  ||¡\}}|dur&| |¡}t||r |ndd�}|S t|ƒs0t d|¡ |  ||¡s8|S | jt	dd|| 
¡ ƒ|d� | j|dd�}| |¡}|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.
        N)Úbranch_namez:Did not find branch or tag '%s', assuming revision or ref.ÚfetchrO   ©rS   Ú
FETCH_HEADr%   )Úarg_revr:   Úmake_newr   r   rH   Úinfork   r2   r   Úto_argsÚget_revision)r3   r7   r6   r=   r#   r   Ú	is_branchr   r   r   Úresolve_revisionÓ   s*   
þþ
zGit.resolve_revisionÚnamec                 C  s   |sdS |   |¡|kS )z§
        Return whether the current commit hash equals the given name.

        Args:
          dest: the repository directory.
          name: a string name.
        F)rt   )r3   r7   rw   r   r   r   r9     s   	zGit.is_commit_id_equalÚ	verbosityrJ   ÚNonec                 C  sj  |  ¡ }t d||t|ƒ¡ |dkrd}n	|dkrd}nd}|  ¡ dkr>ttj dd	¡ƒs>|  	t
d
dg|¢|‘|‘R Ž ¡ n|  	t
d
g|¢|‘|‘R Ž ¡ |jrš|  |||¡}t|dd ƒ}t d||¡ |d u r|  ||j¡s~t
dd| ¡ ƒ}| j	||d� n%|  |¡|kr™d|› �}	dd|d|	g}| j	||d� n
|  |¡}
| |
¡}t d||j¡ | j||d� d S )NzCloning %s%s to %sr   )z--quietrE   r   )z	--verbosez
--progress)rF   é   Ú*PIP_NO_PARTIAL_CLONE_FOR_BROKEN_GIT_SERVERÚnor   z--filter=blob:nonerl   zRev options %s, branch_name %sÚcheckoutrO   rn   zorigin/z-bz--trackzResolved %s to commit %s©rx   )Ú
to_displayrH   rr   r   rL   r
   r.   r/   r0   r2   r   r#   rv   ÚgetattrÚdebugr9   rs   rY   rt   rq   Úupdate_submodules)r;   r7   r6   r=   rx   Úrev_displayÚflagsrl   Úcmd_argsÚtrack_branchr   r   r   r   Ú	fetch_new  sd   ÿþýüûÿ
ý€
û€

zGit.fetch_newr   c                 C  sd   | j tdd|ƒ|d� g }|dkr| d¡ tdg|¢| ¡ ‘R Ž }| j ||d� | j||d� d S )NÚconfigzremote.origin.urlrn   r   rO   r}   r~   )r2   r   Úappendrs   r‚   ©r;   r7   r6   r=   rx   Úextra_flagsr…   r   r   r   ÚswitchQ  s   
þ
z
Git.switchc                 C  s–   g }|dkr|  d¡ |  ¡ dkr| jddg|¢|d� n
| jdg|¢|d� |  |||¡}tddg|¢| ¡ ‘R Ž }| j||d� | j||d	� d S )
Nr   rO   )rE   é	   rm   z--tagsrn   Úresetz--hardr~   )r‰   rL   r2   rv   r   rs   r‚   rŠ   r   r   r   Úupdateg  s"   
þýüz
Git.updatec                 C  sx   | j g d¢ddd|d�}| ¡ }z|d }W n	 ty   t‚w |D ]}| d¡r-|} nq"| d¡d	 }|  | ¡ ¡S )
z¢
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        )rˆ   z--get-regexpzremote\..*\.urlrP   FTrQ   r   zremote.origin.url r_   rE   )r2   Ú
splitlinesÚ
IndexErrorr   rU   ra   Ú_git_remote_to_pip_urlrT   )r3   rM   ÚstdoutÚremotesÚfound_remoteÚremoter6   r   r   r   Úget_remote_url…  s(   
ûÿ
þzGit.get_remote_urlc                 C  sJ   t  d| ¡r| S tj | ¡rt | ¡ ¡ S t | ¡}|r!| 	d¡S t
| ƒ‚)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)Úrer   r.   ÚpathÚexistsÚpathlibÚPathÚas_uriÚ	SCP_REGEXÚexpandr   )r6   Ú	scp_matchr   r   r   r’   £  s   

zGit._git_remote_to_pip_urlc                 C  s8   z| j ddd|d g|dd� W dS  ty   Y dS w )zU
        Check if rev is a commit that is available in the local repository.
        ú	rev-parserO   z--verifyz	^{commit}F)rS   Úlog_failed_cmdT)r2   r   )r3   rM   r#   r   r   r   rj   Â  s   ýýÿzGit.has_commitNc                 C  s*   |d u rd}| j d|gdd|d�}| ¡ S )Nr"   r¡   FT©rC   rD   rS   )r2   rT   )r3   rM   r#   Úcurrent_revr   r   r   rt   Ò  s   üzGit.get_revisionc                 C  sT   | j ddgdd|d� ¡ }tj |¡stj ||¡}tj tj |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.
        r¡   z	--git-dirFTr£   z..)r2   rT   r.   r™   ÚisabsÚjoinÚabspathr   )r3   rM   Úgit_dirÚ	repo_rootr   r   r   Úget_subdirectoryÞ  s   üû
zGit.get_subdirectoryú tuple[str, str | None, AuthInfo]c                   sê   ddl }t|ƒ\}}}}}| d¡rG|dt| d¡ƒ … }||j |¡ dd¡ d¡ }	| d¡d }
|d|
… t	||
d… ||	||fƒ }d|vrgd	|vsQJ ‚| d
d¡}t
ƒ  |¡\}}}| dd¡}n	t
ƒ  |¡\}}}|||fS )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.
        r   NÚfileú/ú\ú+rE   z://zfile:zgit+z
git+ssh://zssh://Ú )Úurllib.requestÚurlsplitÚendswithrV   ÚlstripÚrequestÚurl2pathnamer   ÚfindÚ
urlunsplitr1   Úget_url_rev_and_auth)r3   r6   ÚurllibÚschemeÚnetlocr™   ÚqueryÚfragmentÚinitial_slashesÚnewpathÚ
after_plusr#   Ú	user_passr4   r   r   r¹   ð  s(   
ÿþÿ
zGit.get_url_rev_and_authc                 C  sF   g d¢}|dkr|  d¡ tj tj |d¡¡sd S | j||d� d S )N)Ú	submoduler�   z--initz--recursiver   rO   z.gitmodulesrn   )r‰   r.   r™   rš   r¦   r2   )r3   rM   rx   Úargvr   r   r   r‚     s   

þzGit.update_submodulesc                   sx   t ƒ  |¡}|r
|S z| jddg|ddddd�}W n ty)   t d|¡ Y d S  ty2   Y d S w tj 	| 
d¡¡S )	Nr¡   z--show-toplevelFTÚraise)rS   rC   rD   r\   r¢   zKcould not determine if %s is under git control because git is not availablez
)r1   Úget_repository_rootr2   r   rH   r�   r   r.   r™   Únormpathrb   )r3   rM   ÚlocÚrr4   r   r   rÆ     s,   
úýÿzGit.get_repository_rootÚrepo_urlc                 C  s   dS )zEIn either https or ssh form, requirements must be prefixed with git+.Tr   )rÊ   r   r   r   Úshould_add_vcs_url_prefix8  s   zGit.should_add_vcs_url_prefix)r#   r   r   r$   )r'   r   r(   r   r   r   )r6   r   r7   r   r   r   )r   r@   )rM   r   r   rN   )r7   r   r#   r   r   rZ   )r7   r   r#   r   r   r   )r7   r   r6   r   r=   r   r   r   )r7   r   rw   rN   r   r   )
r7   r   r6   r   r=   r   rx   rJ   r   ry   )r   )rM   r   r   r   )r6   r   r   r   )rM   r   r#   r   r   r   r   )rM   r   r#   rN   r   r   )r6   r   r   r«   )rM   r   rx   rJ   r   ry   )rÊ   r   r   r   )!Ú__name__Ú
__module__Ú__qualname__rw   ÚdirnameÚ	repo_nameÚschemesÚunset_environÚdefault_arg_revÚstaticmethodr&   Úclassmethodr2   r?   rL   rY   r:   rk   rv   r9   r‡   rŒ   r�   r—   r’   rj   rt   rª   r¹   r‚   rÆ   rË   Ú__classcell__r   r   r4   r   r   =   s\    	

--
Fûû r   )r   r   r   r   )-Ú
__future__r   ÚloggingÚos.pathr.   r›   r˜   Úurllib.parserº   Údataclassesr   Útypingr   Úpip._internal.exceptionsr   r   Úpip._internal.utils.miscr   r   r	   r
   Úpip._internal.utils.subprocessr   Ú pip._internal.vcs.versioncontrolr   r   r   r   r   r   r   Úparser²   r¸   Ú	getLoggerrÌ   rH   ÚcompilerG   r   ÚVERBOSErž   r   r   Úregisterr   r   r   r   Ú<module>   s<    $

ÿ

õ
    