3
_Af X                 @   s8  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Zd dlZd dl	Z	d dl
Z
yd dlZW n ek
r|   d dlZY nX d dlZd dlmZ e rd dlZd dlZn&d dlZd dlZejdZee_ee_d dlmZmZ d dlZd dlmZ e r
d dlm Z  nd dl!m Z  d dl"m#Z# d d	l"m$Z$ d d
l"m%Z% d dl&m'Z'm(Z(m)Z) ej*dZ+e, Z-dd Z.dd Z/dd Z0dd Z1dd Z2G dd de3Z4G dd de4Z5G dd de3Z6g Z7e8 Z9da:da;dd Z<d0d d!Z=d"d# Z>ej*d$Z?ej*d%Z@d&d' ZAejBd(d) ZCd*d+ ZDG d,d- d-e3ZEG d.d/ d/e3ZFdS )1    )print_functionN)
is_python3urllib)GitErrorUploadError)Trace)HTTPException)
GitCommand)ssh_sock)terminate_ssh_clients)	R_CHANGESR_HEADSR_TAGSz^[0-9a-f]{40}$c             C   s
   | j tS )N)
startswithr   )rev r   </home/qytech/356xLinux510-101server/.repo/repo/git_config.pyIsChange?   s    r   c             C   s
   t j| S )N)ID_REmatch)r   r   r   r   IsIdC   s    r   c             C   s
   | j tS )N)r   r   )r   r   r   r   IsTagG   s    r   c             C   s   t | pt| pt| S )N)r   r   r   )r   r   r   r   IsImmutableK   s    r   c             C   sH   | j d}t|dk r| j S |d j |d< |d j |d< dj|S )N.   r      r   )splitlenlowerjoin)namepartsr   r   r   _keyO   s    
r#   c               @   s   e Zd ZdZdZedd Zed.ddZd/ddZd0d
dZ	dd Z
dd Zd1ddZdd Zdd Zdd Zdd Zd2ddZdd Zed d! Zed"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- ZdS )3	GitConfigNz~/.gitconfigc             C   s&   | j d kr | tjj| jd| _ | j S )N)
configfile)_ForUserospath
expanduser_USER_CONFIG)clsr   r   r   ForUser]   s    
zGitConfig.ForUserc             C   s   | t jj|d|dS )Nconfig)r%   defaults)r'   r(   r    )r+   gitdirr.   r   r   r   ForRepositoryc   s    zGitConfig.ForRepositoryc             C   sd   || _ || _d | _d | _i | _i | _|| _| jd kr`tjj	tjj
| j dtjj| j  d | _d S )Nz.repo_z.json)filer.   _cache_dict_section_dict_remotes	_branches_jsonr'   r(   r    dirnamebasename)selfr%   r.   ZjsonFiler   r   r   __init__h   s    
zGitConfig.__init__Tc             C   s0   t || jkrdS |r,| jr,| jj|ddS dS )z8Return true if this configuration file has the key.
    T)include_defaultsF)r#   _cacher.   Has)r9   r!   r;   r   r   r   r=   v   s
    
zGitConfig.Hasc             C   s   | j |}|dkrdS |j }d}|jdr>|dd }d}n6|jdrZ|dd }d}n|jdrt|dd }d}d}|jdrd	}yt||d
| S  tk
r   dS X dS )zReturns an integer from the configuration file.

    This follows the git config syntax.

    Args:
      name: The key to lookup.

    Returns:
      None if the value was not defined, or is not a boolean.
      Otherwise, the number itself.
    Nr   ki   mg
   0x   )baser   r   i   r   i   i   @)	GetStringstripendswithr   int
ValueError)r9   r!   vZmultrD   r   r   r   GetInt   s*    




zGitConfig.GetIntc             C   s:   | j |}|dkrdS |j }|dkr*dS |d	kr6dS dS )
zReturns a boolean from the configuration file.
       None : The value was not defined, or is not a boolean.
       True : The value was set to true or yes.
       False: The value was set to false or no.
    NtrueyesTfalsenoF)rL   rM   )rN   rO   )rE   r   )r9   r!   rJ   r   r   r   
GetBoolean   s    
zGitConfig.GetBooleanFc             C   s   y| j t| }W n. tk
r@   | jr8| jj||dS g }Y nX |sV|rR|d S dS g }|j| | jr|j| jj|dd |S )zGet the first value for a key, or None if it is not defined.

       This configuration file is used first, if the key is not
       defined or all_keys = True then the defaults are also searched.
    )all_keysr   NT)r<   r#   KeyErrorr.   rE   extend)r9   r!   rQ   rJ   rr   r   r   rE      s    

zGitConfig.GetStringc             C   s   t |}y| j| }W n tk
r.   g }Y nX |dkrR|rP| j|= | jd| nt|trt|dkrv| j|d npt|dkr| j||d  nR||krt|| j|< | jd||d  x^tdt|D ]}| jd|||  qW n4t|dkp|d |kr|g| j|< | jd|| dS )zSet the value(s) for a key.
       Only this configuration file is modified.

       The supplied value should be either a string,
       or a list of strings (to store multiple values).
    Nz--unset-allr   r   z--replace-allz--add)	r#   r<   rR   _do
isinstancelistr   	SetStringrange)r9   r!   valuekeyoldir   r   r   rX      s,    

zGitConfig.SetStringc             C   s>   y| j | }W n* tk
r8   t| |}|| j |j< Y nX |S )z>Get the remote.$name.* configuration values as an object.
    )r4   rR   Remoter!   )r9   r!   rT   r   r   r   	GetRemote   s    
zGitConfig.GetRemotec             C   s>   y| j | }W n* tk
r8   t| |}|| j |j< Y nX |S )z>Get the branch.$name.* configuration values as an object.
    )r5   rR   Branchr!   )r9   r!   br   r   r   	GetBranch   s    
zGitConfig.GetBranchc             C   s   | j j|t S )z4List all subsection names matching $section.*.*
    )	_sectionsgetset)r9   sectionr   r   r   GetSubSections  s    zGitConfig.GetSubSections c             C   s(   y|| j | kS  tk
r"   dS X dS )z7Does at least one key in section.subsection exist?
    FN)rc   rR   )r9   rf   Z
subsectionr   r   r   
HasSection	  s    zGitConfig.HasSectionc             C   sX   xR| j dD ]D}x>| jd| dD ]*}|dk	r"|j|r"||t|d  S q"W qW |S )z,Resolve any url.*.insteadof references.
    urlzurl.%s.insteadofTN)rg   rE   r   r   )r9   rj   Znew_urlZold_urlr   r   r   UrlInsteadOf  s
    zGitConfig.UrlInsteadOfc             C   s   | j }|d kri }xv| jj D ]h}|jd}dt|krF|d }d}n|d }dj|dd }||krrt ||< || j| || _ qW |S )Nr   r   r   rh   r   r   )r3   r<   keysr   r   r    re   add)r9   dr!   prf   Zsubsectr   r   r   rc     s    


zGitConfig._sectionsc             C   s   | j d kr| j | _ | j S )N)r2   _Read)r9   r   r   r   r<   -  s    

zGitConfig._cachec             C   s&   | j  }|d kr"| j }| j| |S )N)	_ReadJson_ReadGit	_SaveJson)r9   rn   r   r   r   rp   3  s
    
zGitConfig._Readc             C   s   y0t jj| jt jj| jkr.tj| j d S W n tk
rD   d S X y,td| j t	| j}t
j|S Q R X W n$ ttfk
r   tj| j d S X d S )Nz: parsing %s)r'   r(   getmtimer6   r1   platform_utilsremoveOSErrorr   openjsonloadIOErrorrI   )r9   fdr   r   r   rq   :  s    zGitConfig._ReadJsonc             C   sd   y,t | jd}tj||dd W d Q R X W n2 ttfk
r^   tjj| jrZt	j
| j Y nX d S )Nwr   )indent)rx   r6   ry   dumpr{   	TypeErrorr'   r(   existsru   rv   )r9   cacher|   r   r   r   rs   I  s    zGitConfig._SaveJsonc             C   s   i }| j dd}|dkr|S t s,|jd}x\|jdjdD ]H}d|kr\|jdd\}}n|}d}||kr||| j| q>|g||< q>W |S )ze
    Read configuration data from git.

    This internal method populates the GitConfig cache.

    z--nullz--listNzutf-8 
r   )rU   r   decoderstripr   append)r9   crn   liner[   valr   r   r   rr   Q  s    
zGitConfig._ReadGitc             G   sR   dd| j g}|j| td |ddd}|j dkr8|jS tdt||jf  d S )Nr-   z--fileT)capture_stdoutcapture_stderrr   zgit config %s: %s)r1   rS   r	   Waitstdoutr   strstderr)r9   argscommandro   r   r   r   rU   l  s    
zGitConfig._do)N)NN)T)F)rh   )__name__
__module____qualname__r&   r*   classmethodr,   r0   r:   r=   rK   rP   rE   rX   r_   rb   rg   ri   rk   propertyrc   r<   rp   rq   rs   rr   rU   r   r   r   r   r$   X   s.   

	%
$


	r$   c               @   s   e Zd ZdZdZdS )
RepoConfigzUser settings for repo itself.z~/.repoconfig/configN)r   r   r   __doc__r*   r   r   r   r   r   z  s   r   c               @   sD   e Zd ZdZedd Zdd Zdd Zdd	 Zd
d Z	dd Z
dS )RefSpeczA Git refspec line, split into its components:

      forced:  True if the line starts with '+'
      src:     Left side of the line
      dst:     Right side of the line
  c             C   s<   |j dd\}}|jdr,|dd  }d}nd}| |||S )N:r   +r   TF)r   r   )r+   Zrslhsrhsforcedr   r   r   
FromString  s    
zRefSpec.FromStringc             C   s   || _ || _|| _d S )N)r   srcdst)r9   r   r   r   r   r   r   r:     s    zRefSpec.__init__c             C   s<   | j r8|| j krdS | j jdr8|j| j d d r8dS dS )NTz/*r   Fr   )r   rG   r   )r9   r   r   r   r   SourceMatches  s    
 zRefSpec.SourceMatchesc             C   s<   | j r8|| j krdS | j jdr8|j| j d d r8dS dS )NTz/*r   Fr   )r   rG   r   )r9   refr   r   r   DestMatches  s    
 zRefSpec.DestMatchesc             C   s6   | j jdr0| jd d |t| j d d   S | jS )Nz/*r   r   )r   rG   r   r   )r9   r   r   r   r   	MapSource  s    $zRefSpec.MapSourcec             C   s>   d}| j r|d7 }| jr"|| j7 }| jr:|d7 }|| j7 }|S )Nrh   r   r   )r   r   r   )r9   sr   r   r   __str__  s    

zRefSpec.__str__N)r   r   r   r   r   r   r:   r   r   r   r   r   r   r   r   r     s   
r   Tc               C   s   t dkstdtj a dS )z}Should be called once at the start of repo to init ssh master handling.

  At the moment, all we do is to create our lock.
  NzShould only call init_ssh once)_master_keys_lockAssertionError
_threadingLockr   r   r   r   init_ssh  s    r   c              C   s  t j  z|d k	r"d| |f }n| }|tkr2dS t sLdtjksLtjdkrPdS ddd	t  | g}|d k	r~d
t	|g|dd< |ddg }yJt
ddj| tj|tjtjd}|j  |j }|stj| dS W n tk
r   Y nX |d d ddg |dd   }yt
ddj| tj|}W nB tk
rj }	 z$datd| |t	|	f tjd dS d }	~	X nX tjd |j d k	}
|
rdS tj| tj| dS t j  X d S )Nz%s:%sTGIT_SSHwin32cygwinFsshz-ozControlPath %sz-pr   z-Ocheckz: %s )r   r   z-Mz-Nz4
warn: cannot enable ssh control master for %s:%s
%s)r1   )r   r   )r   acquire_master_keys_ssh_masterr'   environsysplatformr
   r   r   r    
subprocessPopenPIPEcommunicatewaitrm   	Exceptionprintr   timesleeppoll_master_processesr   release)hostportr[   Zcommand_baseZcheck_commandZcheck_processZisnt_runningr   ro   eZssh_diedr   r   r   	_open_ssh  s\    




 


r   c              C   s   t   x>tD ]6} ytj| jtj | j  W q tk
r@   Y qX qW td d = t	j
  tdd}|rytjtjj| W n tk
r   Y nX d ad S )NF)create)r   r   r'   killpidsignalSIGTERMr   rw   r   clearr
   ru   rmdirr(   r7   r   )ro   rn   r   r   r   	close_ssh  s     



r   z^([^@:]*@?[^:/]{1,}):z#^([a-z][a-z+-]*)://([^@/]*@?[^/]*)/c             C   s   t j| }|r|jdS d S )Nr   )URI_ALLr   group)rj   r?   r   r   r   GetSchemeFromUrl4  s    

r   c       
      c   sX  | j dr*ytjdd| gtjtjtjd}zd}d}d }d }xX|jD ]N}|j jd}|j |rztjj	|t
|d  }|j |rF|t
|d  }qFW |s|r||fV  d S W d |jj  |j r|jj jd}d|krn|st|tjd	 X W n4 tk
r( }	 z|	jtjkr W Y d d }	~	X nX tj jd
}|rJtjj	|}|d fV  d S )Nzpersistent-zgit-remote-persistent-httpsz-print_config)stdinr   r   zhttp.cookiefile=zhttp.proxy=zutf-8z -print_config)r1   zhttp.cookiefile)r   r   r   r   r   rF   r   r'   r(   r)   r   r   closer   r   readr   r   rw   errnoENOENTr$   r,   rE   )
rj   quietro   ZcookieprefixZproxyprefixZ
cookiefileproxyr   err_msgr   r   r   r   GetUrlCookieFile;  sD    




r   c             C   sx   t j| }|rT|jd}|jd}d|kr:|jd\}}nd }|dkrPt||S dS tj| }|rt|jd}t|S dS )	Nr   r   r   r   git+sshssh+gitF)r   r   r   )r   r   r   r   r   URI_SCP)rj   r?   schemer   r   r   r   r   _preconnectd  s    





r   c               @   sl   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dddZdd Zdd ZdddZdS )r^   z-Configuration options related to a remote.
  c             C   sb   || _ || _| jd| _| jd| _| jd| _| jd| _ttt	j
| jddd| _d | _d S )Nrj   pushurlreviewprojectnamefetchT)rQ   )_configr!   _Getrj   pushUrlr   r   rW   mapr   r   r   _review_url)r9   r-   r!   r   r   r   r:   }  s    zRemote.__init__c       	      C   s   t j }|jd}d}d}xX|D ]P}d| d }|j|dd}x0|D ](}| jj|rDt|t|krD|}|}qDW q W t|dkr| jS | jj||dS )	Nrj   rh   zurl.z
.insteadOfT)rQ   r   r   )r$   r,   rg   rE   rj   r   r   replace)	r9   ZglobCfgZurlListZlongestZ
longestUrlrj   r[   ZinsteadOfListZ	insteadOfr   r   r   
_InsteadOf  s    


zRemote._InsteadOfc             C   s   | j  }t|S )N)r   r   )r9   ZconnectionUrlr   r   r   PreConnectFetch  s    zRemote.PreConnectFetchc             C   s  | j d kr| jd krd S | j}|jdr:|tdd  }|jdd dkrTd| }|jd	rv|d t|td	  }|jd
r|d t|td
  }|jds|d7 }|}|tkrt| | _ ndtjkr tjd j \}}| j	|||| _ | j t|< n|jds|jdr,|| _ | j t|< n`dtjkrL|| _ | j t|< n@y|d }|szt
j }tjj||dj }	ntjj|j }	|	dksd|	kr|| _ n&|	jd}	|	j \}}| j	|||| _ W n tjjk
r }
 ztd| jt|
f W Y d d }
~
X nv tjjk
rH }
 ztd| jt|
f W Y d d }
~
X n: tk
r }
 ztd| j|
jjf W Y d d }
~
X nX | j t|< | j | j S )Nzpersistent-r   r   httphttpsssor   z	http://%sz/Gerritz	/ssh_info/ZREPO_HOST_PORT_INFOzsso:zssh:ZREPO_IGNORE_SSH_INFOZssh_info)contexts   NOT_AVAILABLE   <zutf-8z%s: %s)r   r   r   r   )r   r   r   r   r   rG   REVIEW_CACHEr'   r   _SshReviewUrlssl_create_unverified_contextr   requesturlopenr   r   error	HTTPErrorr   r   URLErrorr   	__class__r   r   )r9   	userEmailZvalidate_certsuZhttp_urlr   r   Zinfo_urlr   infor   r   r   r   	ReviewUrl  s\    





&&(
zRemote.ReviewUrlc             C   s6   | j jd| j }|d kr(|jdd }d|||f S )Nzreview.%s.username@r   zssh://%s@%s:%s/)r   rE   r   r   )r9   r   r   r   usernamer   r   r   r     s    zRemote._SshReviewUrlc             C   st   | j dkst|r|S |jds(t| }x"| jD ]}|j|r0|j|S q0W |jtsZ|S td| j| j |f dS )zCConvert a remote revision string to something we have locally.
    r   zrefs/z%s: remote %s does not have %sN)	r!   r   r   r   r   r   r   r   r   )r9   r   specr   r   r   ToLocal  s    


zRemote.ToLocalc             C   s"   x| j D ]}|j|rdS qW dS )z3True if the remote stores to the tracking ref.
    TF)r   r   )r9   r   r  r   r   r   WritesTo  s    
zRemote.WritesToFc             C   s(   |r
d}n
d| j  }tdd|g| _dS )z0Set the fetch refspec to its default value.
    zrefs/heads/*zrefs/remotes/%s/*TN)r!   r   r   )r9   Zmirrorr   r   r   r   
ResetFetch  s    
zRemote.ResetFetchc             C   sx   | j d| j | jdk	r2| j d| jd | j  n| j d| j | j d| j | j d| j | j dttt| j dS )z+Save this remote to the configuration.
    rj   Nr   r   r   r   r   )	_Setrj   r   r   r   rW   r   r   r   )r9   r   r   r   Save  s    
zRemote.Savec             C   s   d| j |f }| jj||S )Nzremote.%s.%s)r!   r   rX   )r9   r[   rZ   r   r   r   r	    s    zRemote._Setc             C   s   d| j |f }| jj||dS )Nzremote.%s.%s)rQ   )r!   r   rE   )r9   r[   rQ   r   r   r   r     s    zRemote._GetN)F)F)r   r   r   r   r:   r   r   r  r   r  r  r  r
  r	  r   r   r   r   r   r^   y  s   :
	r^   c               @   s>   e Zd ZdZdd Zedd Zdd Zdd	 ZdddZ	dS )r`   z4Configuration options related to a single branch.
  c             C   s@   || _ || _| jd| _| jd}|r6| j j|| _nd | _d S )Nmergeremote)r   r!   r   r  r_   r  )r9   r-   r!   rT   r   r   r   r:     s    
zBranch.__init__c             C   s   | j r| jr| j j| jS dS )z,Convert the merge spec to a local name.
    N)r  r  r  )r9   r   r   r   
LocalMerge)  s    zBranch.LocalMergec          
   C   s   | j jd| jrD| jr(| jd| jj n| jdd | jd| j nXt| j jdD}|jd| j  | jr||jd| jj  | jr|jd| j  W dQ R X dS )	z2Save this branch back into the configuration.
    branchr  Nr  az[branch "%s"]
z	remote = %s
z	merge = %s
)	r   ri   r!   r  r	  r  rx   r1   write)r9   r|   r   r   r   r
  1  s    zBranch.Savec             C   s   d| j |f }| jj||S )Nzbranch.%s.%s)r!   r   rX   )r9   r[   rZ   r   r   r   r	  C  s    zBranch._SetFc             C   s   d| j |f }| jj||dS )Nzbranch.%s.%s)rQ   )r!   r   rE   )r9   r[   rQ   r   r   r   r   G  s    zBranch._GetN)F)
r   r   r   r   r:   r   r  r
  r	  r   r   r   r   r   r`     s   r`   )N)G
__future__r   
contextlibr   ry   r'   rer   r   r   r   	threadingr   ImportErrordummy_threadingr   	pyversionr   urllib.requestr   urllib.errorurllib2imp
new_moduler   r   r   r   ru   
repo_tracer   http.clientr   httplibgit_commandr	   r
   r   git_refsr   r   r   compiler   dictr   r   r   r   r   r#   objectr$   r   r   r   re   r   r   r   r   r   r   r   r   r   contextmanagerr   r   r^   r`   r   r   r   r   <module>   sx   


	  $8

O

) "