
    *1                         d Z ddlmZ ddlZddlZddlmZmZm	Z	 dZ
ddZd Zd Z	 	 	 	 	 	 	 	 dd	Zd
 Zd Zd ZddZd Zd ZddZddZddZy)z~Classes for dealing with git am-style patches.

These patches are basically unified diffs with some extra metadata tacked
on.
    )SequenceMatcherN)BlobCommitS_ISGITLINKi@  c                 0   |xs t        | dd      }t        |t              r|j                  |      }|\  }}| j	                  d|j
                  z   dz   t        j                  |j                        j                  |      z   dz          | j	                  d|j                  z   dz          | j	                  dt        j                  d      j                  |      z   dz          | j	                  d	||fz  j                  |      |j                  z   dz          | j	                  d       | j	                  d
       	 ddl}|j                  dg|j                  |j                        }	|	j                  |      \  }
}| j	                  |
       | j	                  d       | j	                  |       | j	                  d       |ddlm} | j	                  d|z         y| j	                  |j                  |      dz          y# t         t"        f$ r Y tw xY w)zWrite a individual file patch.

    Args:
      commit: Commit object
      progress: Tuple with current patch number and total.
    Returns:
      tuple with filename and contents
    encodingasciis   From        
   From: s   Date: z%a, %d %b %Y %H:%M:%S %ZzSubject: [PATCH %d/%d]    ---
r   Ndiffstat)stdoutstdin   -- 
)__version__s   Dulwich %d.%d.%d
)getattr
isinstancestrencodewriteidtimectimecommit_timeauthorstrftimemessage
subprocessPopenPIPEcommunicateImportErrorOSErrordulwichr   )fcommitcontentsprogressversionr   numtotalr   pr   _dulwich_versions                 lib/third_party/dulwich/patch.pywrite_commit_patchr1   (   s    :71j':H(C ??8,LS%GG
))	
	 **V''
(
/
/
9	: 		 GGI%-.GGDMM"<=DDXNNQVV GG	"c5\	199(C
..	
	
 GGENGGHL
  
 h/1		GGHGGH:	%78	x(501 ! s   =-H HHc                     | j                   j                  d      }|j                         d   j                  dd      S )zrDetermine the summary line for use in a filename.

    Args:
      commit: Commit
    Returns: Summary string
    replace)errorsr    -)r   decode
splitlinesr3   )r'   decodeds     r0   get_summaryr:   ]   s<     nn##9#5G"**344    c                 t    | dz   }|| z
  }|dk(  rdj                  |      S |s|dz  }dj                  ||      S )z Convert range to the "ed" format   z{}z{},{})format)startstop	beginninglengths       r0   _format_range_unifiedrC   i   sI     	IE\F{{{9%%Q	>>)V,,r;   c
              #     K   d}
t        d| |      j                  |      D ]R  }|
sd}
|rdj                  |      nd}|rdj                  |      nd}dj                  |j                  |      ||      j	                  |	       dj                  |j                  |      ||      j	                  |	       |d   |d	   }}t        |d
   |d         }t        |d   |d         }dj                  |||      j	                  |	       |D ]d  \  }}}}}|dk(  r| || D ]	  }d|z      |dv r| || D ]  }|d	d dk(  s|dz  }d|z     |dv sG||| D ]  }|d	d dk(  s|dz  }d|z     f U yw)zdifflib.unified_diff that can detect "No newline at end of file" as
    original "git diff" does.

    Based on the same function in Python2.7 difflib.py
    FNTz	{} z
--- {}{}{}z
+++ {}{}{}r   r=            z@@ -{} +{} @@{}equalr
   )r3   deleter   s   
\ No newline at end of file
   -)r3   insert   +)r   get_grouped_opcodesr>   r7   r   rC   )abfromfiletofilefromfiledate
tofiledatenlinetermtree_encodingoutput_encodingstartedgroupfromdatetodatefirstlastfile1_rangefile2_rangetagi1i2j1j2lines                           r0   unified_diffrh   u   s    " G q!,@@CG6Bv}}\2H2<V]]:."F%%.(f_%& %%m,fhf_%& Ahb	t+E!Hd1g>+E!Hd1g>&&{KJQQ
 	
 $)CRRg~bHD+% %++bHD9- CC+% % ++bHD9- CC+% % $)' Ds   EE8$E8c                     d| dt          v S )z}See if the first few bytes contain any null characters.

    Args:
      content: Bytestring to check for binary content
        N)FIRST_FEW_BYTEScontents    r0   	is_binaryrn      s     G,_---r;   c                     | y| d d S )Ns   0000000    )hexshas    r0   shortidrs      s    ~bqzr;   c                     | y|dz   | z   S )Ns	   /dev/null   /rq   )r-   roots     r0   patch_filenamerw      s    yd{Qr;   c                    |\  }}}|\  }}	}
t        |d      }t        |d      }fd}d }| j                  t        ||f||	f||
f              |||      } ||	|
      }|sJt        |j                        st        |j                        r d|z   dz   |z   dz   }| j                  |       y| j                  t         ||       ||      ||             y)	a  Write the diff for an object.

    Args:
      f: File-like object to write to
      store: Store to retrieve objects from, if necessary
      old_file: (path, mode, hexsha) tuple
      new_file: (path, mode, hexsha) tuple
      diff_binary: Whether to diff files even if they
        are considered binary files by is_binary().

    Note: the tuple elements should be None for nonexistant files
       a   bc                     |t        j                  d      S t        |       rt        j                  d|z   dz         S |   S )Nr;   s   Subproject commit r   )r   from_stringr   )moderr   stores     r0   rm   z"write_object_diff.<locals>.content   sG    >##C((##$9F$BU$JKK= r;   c                 *    | sg S | j                         S Nr8   rl   s    r0   linesz write_object_diff.<locals>.lines   s    I%%''r;   s   Binary files s    and s    differ
N)rw   
writelinesgen_diff_headerrn   datar   rh   )r&   r~   old_filenew_filediff_binaryold_pathold_modeold_idnew_pathnew_modenew_idpatched_old_pathpatched_new_pathrm   r   old_contentnew_contentbinary_diffs    `                r0   write_object_diffr      s    $, Xx#+ Xx%h5%h5!( LL8,x.BVVDTU (F+K(F+KIk&6&679[EUEU;V  	 	 	
	k"k"  		
r;   c              #     K   | \  }}|\  }}|\  }}|||}|||}t        |d      }t        |d      }d|z   dz   |z   dz    ||k7  rG|/|d|z  j                  d       d	|z  j                  d       nd
|z  j                  d       dt        |      z   dz   t        |      z    ||d|z  j                  d       d yw)zWrite a blob diff header.

    Args:
      paths: Tuple with old and new path
      modes: Tuple with old and new modes
      shas: Tuple with old and new shas
    Nry   rz   s   diff --git r
   r   zold file mode %o
r	   znew file mode %o
zdeleted file mode %o
s   index s   ..z %o)rw   r   rs   )	pathsmodesshasr   r   r   r   old_shanew_shas	            r0   r   r      s     !Xx XxWgH0H0h-Hh-H
8
#d
*X
5
==8#+h6>>wGG'(2::7CC+h6>>wGG
gg&
&
.1A
AA 4x''00
Ks   CCc                    |\  }}}|\  }}}t        |d      }	t        |d      }
d }| j                  t        ||f||ft        |dd      t        |dd      f              ||      } ||      }| j                  t	        |||	|
             y)a  Write blob diff.

    Args:
      f: File-like object to write to
      old_file: (path, mode, hexsha) tuple (None if nonexisting)
      new_file: (path, mode, hexsha) tuple (None if nonexisting)

    Note: The use of write_object_diff is recommended over this function.
    ry   rz   c                 *    | | j                         S g S r   r   )blobs    r0   r   zwrite_blob_diff.<locals>.lines,  s    ??$$Ir;   r   N)rw   r   r   r   rh   )r&   r   r   r   r   old_blobr   r   new_blobr   r   r   old_contentsnew_contentss                 r0   write_blob_diffr     s     &."Xx%-"Xx%h5%h5 LLx x XtT*GHdD,IJ	
 ?L?LLL\<1ACSTr;   c           	      |    |j                  ||      }|D ]%  \  \  }}\  }}	\  }
}t        | ||||
f||	|f|       ' y)zWrite tree diff.

    Args:
      f: File-like object to write to.
      old_tree: Old tree id
      new_tree: New tree id
      diff_binary: Whether to diff files even if they
        are considered binary files by is_binary().
    )r   N)tree_changesr   )r&   r~   old_treenew_treer   changesoldpathnewpatholdmodenewmodeoldshanewshas               r0   write_tree_diffr   @  s]       84GDK@'.Wg0@gv&gv&#	
 ELr;   c                 |   |xs t        | dd      }|xs d}| j                         }t        |t              rKt        t        j
                  dd      r0t        j
                  j                         }|j                  |      }n/t        j
                  j                         }|j                  |      }t        ||      S )zParse a git-am-style patch and split it up into bits.

    Args:
      f: File-like object to parse
      encoding: Encoding to use when creating Git objects
    Returns: Tuple with commit object, diff contents and git version
    r   r	   BytesParserN)r   readr   bytesemailparserr   
parsebytesParserparsestrparse_patch_message)r&   r   r(   r   msgs        r0   git_am_patch_splitr   U  s     :71j':H"7HvvxH(E"wu||]D'Q))+)$$&ooh'sH--r;   c                 2   t               }| d   j                  |      |_        | d   j                  |      |_        	 | d   j	                  d      }| d   j	                  d|      }| d   |dz   d }|j                  dd      dz   j                  |      |_        d	}| j                  d	
      }|j                  d	      }t        |      }	|	D ]n  }
|
dk(  r ng|rN|
j                  d      r"|
t        d      d j                         |_        n|xj                  d|
z   z  c_        d}Z|xj                  |
z  c_        p d}|	D ]  }
|
dk(  r n||
z  } 	 t        |	      j                  d      }|||fS # t
        $ r	 | d   }Y w xY w# t        $ r d}Y 'w xY w)zExtract a Commit object and patch from an e-mail message.

    Args:
      msg: An email message (email.message.Message)
      encoding: Encoding to use to encode Git commits
    Returns: Tuple with commit object, diff contents and git version
    fromsubjectz[PATCHz] rG   N
rE   T)r7   r   r   r   Fr;   r   )r   r   r   	committerindex
ValueErrorr3   r   get_payloadr8   iter
startswithlenrstripnextStopIteration)r   r   cpatch_tag_startcloser   r^   bodyr   	line_iterrg   diffr*   s                r0   r   r   i  s    	A6{!!(+AHf+$$X.AK.i...x8 I$$T?;i.-r*T199(CAIE??$?'DOOD!EUI8y)I 0188:		UT\)	EIII  D8 y/((/ dGA  !i.!<  s#   E3 F 3FFFF)NN)rE   rE   rE   rE   rH   r   utf-8r   )Fr   )__doc__difflibr   email.parserr   r   dulwich.objectsr   r   r   rk   r1   r:   rC   rh   rn   rs   rw   r   r   r   r   r   r   rq   r;   r0   <module>r      s   * $    22j5	- 3&l.6
tB F
*.(-r;   