o
    |ŸŽi½E  ã                   @   sú   d dl 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	m
Z
mZ d dlmZmZ d dl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„ Z(G dd„ deƒZ)e *e)¡ dS )é    N)ÚListÚOptionalÚTuple)Ú
BadCommandÚInstallationError)Ú
HiddenTextÚdisplay_pathÚhide_url)Ú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[^:]*)
$c                 C   s   t t | ¡ƒS ©N)ÚboolÚ
HASH_REGEXÚmatch)Úsha© r   ú_C:\Users\psant\Downloads\Anu Raj Backend\school\venv\Lib\site-packages\pip/_internal/vcs/git.pyÚlooks_like_hash4   s   r   c                       s  e Zd ZdZdZdZdZdZdZe	dd„ ƒZ
d	d
„ Zdeedf fdd„Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Zdd„ Zdd„ Zedd „ ƒZe	d!d"„ ƒZed#d$„ ƒZed2d&d'„ƒZed(d)„ ƒZe‡ fd*d+„ƒZed,d-„ ƒZe‡ fd.d/„ƒZe	d0d1„ ƒZ ‡  Z!S )3ÚGitÚgitz.gitÚclone)zgit+httpz	git+httpszgit+sshzgit+gitzgit+file)ÚGIT_DIRÚGIT_WORK_TREEÚHEADc                 C   s   | gS r   r   ©Úrevr   r   r   Úget_base_rev_argsE   s   zGit.get_base_rev_argsc                 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)ÚselfÚurlÚdestÚ_Úrev_optionsÚis_tag_or_branchr   r   r   Úis_immutable_rev_checkoutJ   s   ÿzGit.is_immutable_rev_checkoutÚreturn.c                 C   s:   | j dgddd�}t |¡}|sdS tdd„ | ¡ D ƒƒS )NÚversionFT)Úshow_stdoutÚstdout_onlyr   c                 s   s   � | ]}t |ƒV  qd S r   )Úint)Ú.0Úcr   r   r   Ú	<genexpr>b   s   € z&Git.get_git_version.<locals>.<genexpr>)Úrun_commandÚGIT_VERSION_REGEXr   ÚtupleÚgroups)r&   r.   r   r   r   r   Úget_git_version[   s   ÿ
zGit.get_git_versionc                 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   ©é   FT©Úextra_ok_returncodesr/   r0   Úcwdzrefs/heads/N)r5   ÚstripÚ
startswithÚlen)ÚclsÚlocationÚargsÚoutputÚrefr   r   r   Úget_current_branchd   s   û
zGit.get_current_branchc              	   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)r?   r/   r0   Úon_returncodeÚ
úú é   )Úmaxsplitzunexpected show-ref line: zrefs/remotes/origin/z
refs/tags/N)r5   r@   ÚsplitÚrstripÚ
ValueErrorÚget)rC   r(   r!   rF   Ú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/TFN)rA   r   Ú
has_commit)rC   r(   r!   r   r   r   Ú_should_fetch­   s   

zGit._should_fetchc                 C   s¨   |j }|dus	J ‚|  ||¡\}}|dur&| |¡}|r!||_|S 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.
        Nz:Did not find branch or tag '%s', assuming revision or ref.Úfetchr:   ©r?   Ú
FETCH_HEADr    )Úarg_revr%   Úmake_newÚbranch_namer   ÚloggerÚwarningr[   r5   r
   Úto_argsÚget_revision)rC   r(   r'   r*   r!   r   Ú	is_branchr   r   r   Úresolve_revisionÅ   s.   


þþþ
zGit.resolve_revisionc                 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.
        FN)re   )rC   r(   Únamer   r   r   r$   ò   s   
zGit.is_commit_id_equalc           	      C   sî   |  ¡ }t d||t|ƒ¡ |  tdd||ƒ¡ |jr^|  |||¡}t|dd ƒ}|d u rC|  	||j¡sBtdd| 
¡ ƒ}| j||d� n%|  |¡|kr]d|› �}dd|d	|g}| j||d� n
|  |¡}| |¡}t d
||j¡ |  |¡ d S )NzCloning %s%s to %sr   r:   ra   Úcheckoutr]   zorigin/z-bz--trackzResolved %s to commit %s)Ú
to_displayrb   Úinfor   r5   r
   r!   rg   Úgetattrr$   rd   rH   re   r`   Úupdate_submodules)	r&   r(   r'   r*   Úrev_displayra   Úcmd_argsÚtrack_branchr   r   r   r   Ú	fetch_new  s.   
ÿ€

ÿ€

zGit.fetch_newc                 C   sB   | j tdd|ƒ|d� tdd| ¡ ƒ}| j ||d� |  |¡ d S )NÚconfigzremote.origin.urlr]   ri   r:   )r5   r
   rd   rm   ©r&   r(   r'   r*   ro   r   r   r   Úswitch%  s   
þz
Git.switchc                 C   sn   |   ¡ dkr| jg d¢|d� n	| jddg|d� |  |||¡}tddd| ¡ ƒ}| j||d� |  |¡ d S )N)r<   é	   )r\   r:   z--tagsr]   r\   r:   Úresetz--hard)r9   r5   rg   r
   rd   rm   rs   r   r   r   Úupdate0  s   z
Git.updatec                 C   sx   | j g d¢ddd|d�}| ¡ }z|d }W n	 ty   t‚w |D ]}| d¡r-|} q.q"| d¡d	 }|  | ¡ ¡S )z¢
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        )rr   z--get-regexpzremote\..*\.urlr;   FTr=   r   zremote.origin.url rM   r<   N)r5   Ú
splitlinesÚ
IndexErrorr   rA   rP   Ú_git_remote_to_pip_urlr@   )rC   rD   ÚstdoutÚremotesÚfound_remoteÚremoter'   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/\3N)Úrer   ÚosÚpathÚexistsÚpathlibÚPurePathÚas_uriÚ	SCP_REGEXÚexpandr   )r'   Ú	scp_matchr   r   r   rz   ^  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-parser:   z--verifyzsha^F)r?   Úlog_failed_cmdTN)r5   r   )rC   rD   r!   r   r   r   rZ   ~  s   ýýÿzGit.has_commitNc                 C   s*   |d u rd}| j d|gdd|d�}| ¡ S )Nr   rŠ   FT©r/   r0   r?   )r5   r@   )rC   rD   r!   Úcurrent_revr   r   r   re   �  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..N)r5   r@   r�   r‚   ÚisabsÚjoinÚabspathr   )rC   rD   Úgit_dirÚ	repo_rootr   r   r   Úget_subdirectoryœ  s   üû
zGit.get_subdirectoryc                    sâ   t |ƒ\}}}}}| d¡rC|dt| d¡ƒ … }|tj |¡ dd¡ d¡ }| d¡d }	|d|	… t	||	d… ||||fƒ }d|vrcd|vsMJ ‚| 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.
        ÚfileNú/ú\ú+r<   z://zfile:zgit+z
git+ssh://zssh://Ú )ÚurlsplitÚendswithrB   ÚlstripÚurllibÚrequestÚurl2pathnameÚreplaceÚfindÚ
urlunsplitÚsuperÚget_url_rev_and_auth)rC   r'   ÚschemeÚnetlocr‚   ÚqueryÚfragmentÚinitial_slashesÚnewpathÚ
after_plusr!   Ú	user_pass©Ú	__class__r   r   r£   ¯  s&   

þÿÿ
zGit.get_url_rev_and_authc                 C   s0   t j t j |d¡¡sd S | jg d¢|d� d S )Nz.gitmodules)Ú	submodulerw   z--initz--recursiver:   r]   )r�   r‚   rƒ   r�   r5   )rC   rD   r   r   r   rm   Ñ  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)r?   r/   r0   rJ   r‹   zKcould not determine if %s is under git control because git is not availablez
)r¢   Úget_repository_rootr5   r   rb   Údebugr   r�   r‚   ÚnormpathrQ   )rC   rD   ÚlocÚrr¬   r   r   r°   Û  s*   
úÿÿzGit.get_repository_rootc                 C   s   dS )zNIn either https or ssh form, requirements must be prefixed with git+.
        TNr   )Úrepo_urlr   r   r   Úshould_add_vcs_url_prefixò  s   zGit.should_add_vcs_url_prefixr   )"Ú__name__Ú
__module__Ú__qualname__rh   ÚdirnameÚ	repo_nameÚschemesÚunset_environÚdefault_arg_revÚstaticmethodr"   r,   r   r1   r9   ÚclassmethodrH   r%   r[   rg   r$   rq   rt   rw   r   rz   rZ   re   r“   r£   rm   r°   r¶   Ú__classcell__r   r   r¬   r   r   9   sT    
	

.

,
#



!
	r   )+ÚloggingÚos.pathr�   r„   r€   Úurllib.parserœ   Úurllib.requestÚtypingr   r   r   Úpip._internal.exceptionsr   r   Úpip._internal.utils.miscr   r   r	   Úpip._internal.utils.subprocessr
   Ú pip._internal.vcs.versioncontrolr   r   r   r   r   r   r   Úparser™   r¡   Ú	getLoggerr·   rb   Úcompiler6   r   ÚVERBOSEr‡   r   r   Úregisterr   r   r   r   Ú<module>   s6    $

ÿ
	÷   D