ó
WJKc           @   sg   d  Z  d d l Z d d l Z d d l Z e j d e j  Z d   Z d   Z d   Z	 d   Z
 d S(   s  
.. highlight:: diff

This module contains algorithms for performing conflict
resolution after Git performs its recursive merge.  It
defines a simple domain specific language (that, at
its simplest form, merely involves copying conflict markers
and writing in the form that they should be resolved as) for
specifying how to resolve conflicts.  These are mostly relevant
for resolving conflicts in configuration files.

The conflict resolution DSL is described here:

Resolutions are specified as input-output pairs.  An input
is a string with the conflict resolution markers ``("<" * 7,
"=" * 7 and ">" * 7)``, with the HEAD content above the equals
divider, and the upstream content below the equals divider.
Lines can also be marked as ``***N***`` where N is a natural
number greater than 0 (i.e. 1 or more), which means that
an arbitrary number of lines may be matched and available for output.

Output is a list of integers and strings.  Integers expand
to lines that were specified earlier; -1 and 0 are special integers
that correspond to the entire HEAD text, and the entire upstream
text, respectively.  Strings can be used to insert custom lines.

The DSL does not currently claim to support character level granularity.
It also does not claim to support contiguous conflicts.
Our hope is that this simple syntax will be sufficient to cover
most common merge failures.

Here are some examples::

    <<<<<<<
    downstream
    |||||||
    common
    =======
    upstream
    >>>>>>>

With ``[-1]`` would discard all upstream changes, whereas with ``[0]``
would discard downstream changes (you would probably want to be
careful about wildcarding in the upstream string).

Pattern matching in action::

    <<<<<<<
    ***1***
    old upstream
    ***2***
    old upstream
    ***3***
    =======
    new upstream
    >>>>>>>

With ``[0, 1, 2, 3]`` would resolve with the new upstream text, and
then the user matched globs.
i˙˙˙˙Ns   ^\*\*\*(\d+)\*\*\*\
c         C   s	  d j  |  j   j t  d d ! j d  \ } } } d   } | j d  \ } } } | sg d } n  | | d d  \ } } | | d d t |   \ }	 }
 | | d	 d t |  t |
   \ } } | j |  | j |
  d
 | d |	 d | d | f S(   s  
    Translates a specification string into a regular expression tuple.
    Note that pattern matches are out of order, so the second element
    of the tuple is a dict specified strings to subpattern numbers.
    Requires re.DOTALL for correct operation.
    t    i   i˙˙˙˙s   =======
c         S   sŚ   t  j t |   } d } i | | 6} xl t t j t t g  |  D]L \ } } | r} | d 7} | d 7} | | t |  <qD | t  j	 |  7} qD Wd | d | f S(   NR    s   (.*\
)i   t   (t   )(
   t   ret   splitt   re_vart   zipt	   itertoolst   cyclet   Falset   Truet   intt   escape(   t   textt	   fullmatcht   matchnot
   text_splitt   rett   mappingst   is_vart   line(    (    s<   /afs/athena.mit.edu/contrib/scripts/wizard/wizard/resolve.pyt   regexifyL   s    +

s   |||||||
s   ***9999***
iţ˙˙˙i    s   <<<<<<<[^
]*\
s   \|\|\|\|\|\|\|\
s	   =======\
s   >>>>>>>[^
]*(\
|$)(   t   joint   stript
   splitlinesR
   t	   partitiont   lent   update(   t   spect   ourst   _t   theirsR   R   t   commont
   ours_regext   ours_mappingst   common_regext   common_mappingst   theirs_regext   theirs_mappings(    (    s<   /afs/athena.mit.edu/contrib/scripts/wizard/wizard/resolve.pyt   spec_to_regexD   s    7		",c            s%     f d   } d j  t | |    S(   s   
    Converts a list of replacement strings and or references
    into a replacement string appropriate for a regular expression.
    c            s*   t  |   t k r d   |  S|  d Sd  S(   Ns   \%ds   
(   t   typeR   (   t   r(   R   (    s<   /afs/athena.mit.edu/contrib/scripts/wizard/wizard/resolve.pyt   ritem_to_stringh   s    R    (   R   t   map(   t   resultR   R*   (    (   R   s<   /afs/athena.mit.edu/contrib/scripts/wizard/wizard/resolve.pyt   result_to_replc   s    c      
   C   sE  t  |  \ } } t j | t j  } t | |  } d } d } d }	 xö |  j t  D]ĺ }
 |	 d k r |
 j d  r d }	 nT |	 d k rŚ |
 j d  rŚ d }	 n0 |	 d k sÍ |	 d k rÖ |
 j d  rÖ d }	 n  |	 d k r |
 j d	  r d }	 | |
 7} | | j | |  7} d } qX |	 r3| |
 7} qX | |
 7} qX W| S(
   s   
    Given a conflicted file, whose contents are ``contents``, attempt
    to resolve all conflicts that match ``spec`` with ``result``.
    R    i    s   <<<<<<<i   s   |||||||i   s   =======i   s   >>>>>>>(	   R'   R   t   compilet   DOTALLR-   R   R
   t
   startswitht   sub(   t   contentsR   R,   t   rstringR   t   regext   replR   t   conflictt   statusR   (    (    s<   /afs/athena.mit.edu/contrib/scripts/wizard/wizard/resolve.pyt   resolveo   s,    		'	
	c         C   s
   d |  k S(   sO   
    Given ``contents``, return ``True`` if there are any conflicts in it.
    s   <<<<<<<(    (   R2   (    (    s<   /afs/athena.mit.edu/contrib/scripts/wizard/wizard/resolve.pyt   is_conflict   s    (   t   __doc__R   R   t   loggingR.   t	   MULTILINER   R'   R-   R8   R9   (    (    (    s<   /afs/athena.mit.edu/contrib/scripts/wizard/wizard/resolve.pyt   <module><   s   			