
    (Gj[                       d Z 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Z
dZdZdZdZd	Zd
ZdZe
ddZdZd[dZd\dZd]dZd^dZd_dZd`d Zdad#Zdbd%Zdbd&Zdcd'Zddd*Zded-Zdfd.Zdgd0Z dhd3Z!did6Z"djd7Z#dkd8Z$dkd9Z%dkd:Z&dld<Z'dmd?Z(dnd@Z)dodAZ*dodBZ+dpdDZ,dodEZ-dodFZ.dqdHZ/drdIZ0dsdJZ1dtdLZ2dtdMZ3dsdNZ4dndOZ5dudQZ6dvdSZ7dwdVZ8drdWZ9dxdYZ:dS )yuw  Backend git operations for the desktop coding rail + Codex-style review pane.

The desktop's git affordances (coding-rail status, worktree lanes, review pane,
branch switch) run as Electron-local git on the user's machine. On a *remote*
gateway those would operate on the wrong filesystem, so this module mirrors them
over the dashboard's authenticated REST surface — the same pattern as ``/api/fs``.

Everything shells out to the system ``git`` (and ``gh`` for ship info / PRs).
Reads degrade to ``None`` / empty on a non-repo; mutations raise so the renderer
can surface a toast. Callers pass an already path-hardened ``cwd``.
    )annotationsN)Path   i   i   i  i P   )mainmaster)timeoutcwdstrargs	list[str]r	   intreturntuple[int, str, str]c                   	 t          j        dg|| dd|          }n# t          t           j        f$ r Y dS w xY w|j        |j        |j        fS )zRun ``git`` in ``cwd``. Returns (returncode, stdout, stderr); never raises
    on a non-zero exit (callers decide what an error means).gitTr
   capture_outputtextr	   )    zgit invocation failed)
subprocessrunOSErrorSubprocessError
returncodestdoutstderr)r
   r   r	   procs       8/home/rurouni/.hermes/hermes-agent/hermes_cli/web_git.py_gitr!       su    	.~NTN
 
 
 Z/0 . . .---.?DK44s    99c                >    t          | |          \  }}}|dk    r|ndS )z.stdout of a git command, or "" on any failure.r   r   r!   )r
   r   codeout_s        r    _git_outr'   0   s'    T??LD#q!))33#    Nonec                    t          | |          \  }}}|dk    r:t          |                                pdd                    |           d          dS )z@Run a git mutation, raising RuntimeError with stderr on failure.r   zgit  z failedN)r!   RuntimeErrorstripjoin)r
   r   r$   r&   errs        r    _git_okr0   6   sV    T??LD!Sqyy399;;H*H$*H*H*HIII yr(   boolc                h    	 t          |                                           S # t          $ r Y dS w xY w)NF)r   is_dirr   r
   s    r    _is_dirr5   =   sA    Cyy!!!   uus    # 
11rawc                   t          | pd                                          }d|vr|S |                    d          \  }}}|rRd|v rN|                    d          \  }}}|                    d          \  }}}| | |                     dd          S |                    d          d                                         S )ur   ``old => new`` (and ``dir/{old => new}/f``) → the NEW path, so a row
    addresses the real file for diff/stage.r   z => {}z///)r   r-   	partitionreplacesplit)r6   pathheadr&   tailinnersuffixtos           r    resolve_rename_pathrE   G   s     syb>>!!DTNN3''MD!T 8t>>#..q&??6**1b$$F$$,,T3777::fb!'')))r(   dict[str, tuple[int, int]]c                z   t          | ddg|          }i }|                                D ]}|                    d          }t          |          dk     r+|d         dk    rdnt	          |d         pd          }|d         dk    rdnt	          |d         pd          }||f|t          |d                   <   |S )	uP   ``git diff --numstat`` → {path: (added, removed)}; binary files (``-``) → 0.diffz	--numstat	   r   -r      )r'   
splitlinesr>   lenr   rE   )r
   r   r%   countslinepartsaddedremoveds           r    _numstatrT   U   s    
34t4
5
5C)+F   A A

4  u::>>1X__#eAhm!*<*<Qx3!!CaA,>,>160@"58,,--Mr(   relc                n   	 t          |           |z  }|                                }t          j                            |          r|j        t          k    rdS |                                }d|v rdS |                    d          }|r|	                    d          s|dz   n|S # t          $ r Y dS w xY w)u   Line count of an untracked file (newlines + a final unterminated line),
    so the review tree can show +N for new files. Binary / oversized → 0.r          
r   )r   statosr?   isfilest_size_UNTRACKED_LINE_MAX_BYTES
read_bytescountendswithr   )r
   rU   targetstdataliness         r    _untracked_insertionsre   c   s    cS[[]]w~~f%% 	6O)O)O1  ""D==1

5!! Hu)=)=Huqyy5H   qqs   AB& B& 32B& &
B43B4files
list[dict]c                    |D ]?}|d         dk    r1|d         dk    r%|d         dk    rt          | |d                   |d<   @d S )Nstatus?rR   r   rS   r?   re   )r
   rf   files      r    _fill_untracked_countsrm   t   sb     E E>S  T']a%7%7DOq<P<P1#tF|DDDME Er(   
str | Nonec                    g }t          | g d                                          }|r|                    |           |g dz  }|D ]-}t          | dd|g                                          }|r|c S .dS )zCMerge-base with the remote default branch for "all branch changes".	rev-parse--abbrev-reforigin/HEAD)zorigin/mainzorigin/masterr   r   z
merge-baseHEADN)r'   r-   append)r
   
candidatesr@   refbases        r    _branch_basery   z   s    JCEEEFFLLNND  $DDDDJ  lFC899??AA 	KKK	4r(   c                   t          | g d                                          }|r"|dk    r|                    dd          d         S dD ]=}t          | ddd	|g          \  }}}|d
k    r|                    d          d         c S >dS )uD   The repo's trunk name ("main"/"master"/…), preferring origin/HEAD.rp   rs   r:   r   r;   )zrefs/heads/mainzrefs/heads/masterzrefs/remotes/origin/mainzrefs/remotes/origin/masterrq   --verify--quietr   N)r'   r-   r>   r!   )r
   r@   rw   r$   r&   s        r    _default_branch_namer}      s    CEEEFFLLNND &%%zz#q!!"%% & & #ZCHII
a19999S>>"%%%% 4r(   c              #  b  K   |                      d          }d}|t          |          k     r||         }|r|d         nd}|dk    rdd|dd         fV  n|dk    r;d|                     d	          d
         |                     d	d          d         fV  n||dv rx|                     d	          d
         }|dk    r|                     d	d          d         n|                     d	d          d         }|dk    r|d
z  }||t          |          fV  |d
z  }|t          |          k     dS dS )zYield (tag, xy, path) per changed file from ``git status --porcelain=v2 -z``,
    skipping branch headers and the rename/copy origin-path records. One walker
    feeds the rail, the review list, and the commit flow. r   r   rj   ??rL   Nur+   r   
   r;   12r      	   r   )r>   rN   rE   )r6   recordsirectagxyr?   s          r    _walk_entriesr      s]      iiooG	A
c'll

aj#c!ff#::tSW$$$$$CZZsyy~~a(#))C*<*<R*@@@@@@J3"B,/3JJ399S!$$R((CIIc1<M<Mb<QDczzQr.t444444	Q c'll





r(   r   r   c                    | dv o	|d         dvS )z1A tracked entry whose index (staged) code is set.r   r   .rj    )r   r   s     r    _entry_stagedr      s    *8Aj!88r(   r?   dictc                    t          |          dk    r|d         nd}|t          | |          | dk    p| dv o|dv| dk    | dk    dS )Nr   r   rj   r   r   r   )r?   stagedunstaged	untracked
conflicted)rN   r   )r   r   r?   ys       r    	_classifyr      se    R11#AR((3JM3*#4#L*9LCZSj  r(   c                    | dv r| dk    r|                                  ndS |d         dk    r|d         nt          |          dk    r|d         nd}|dk    r|nd                                 S )N)rj   r   r   rj   r   r   r   M)upperrN   )r   r   r$   s      r    _status_letterr      st    
j!Sjjsyy{{{c1qESLL2a55B!r!uuDCKKDDS//111r(   dict | Nonec                H    t                     sdS t           g d          \  }}}|dk    rdS d}d}dx}}|                    d          D ]}|                    d          r$|t	          d          d         }	|	dk    }|rdn|	};|                    d          r||                                d	d         D ]_}
|
                    d
          rt          |
dd         pd          }1|
                    d          rt          |
dd         pd          }`d t          |          D             }dx}}t           dg                                          D ]\  }}||z  }||z  }|t           fd|dt                   D                       z  }|t                     |||t          d |D                       t          d |D                       t          d |D                       t          d |D                       t	          |          |||dd         dS )zDCompact working-tree status for the coding rail. None on a non-repo.N)ri   --porcelain=v2z--branch-zr   Fr   z# branch.head z
(detached)z# branch.ab rL   +r   rK   c                8    g | ]\  }}}t          |||          S r   )r   ).0r   r   r?   s       r    
<listcomp>zrepo_status.<locals>.<listcomp>   s*    NNN-#r4YsB%%NNNr(   rt   c              3  T   K   | ]"}|d          
t          |d                   V  #dS )r   r?   Nrk   )r   fr
   s     r    	<genexpr>zrepo_status.<locals>.<genexpr>   s>      nn1_`al_mn&sAfI66nnnnnnr(   c              3  &   K   | ]}|d          V  dS )r   Nr   r   r   s     r    r   zrepo_status.<locals>.<genexpr>   s&      11aak111111r(   c              3  &   K   | ]}|d          V  dS )r   Nr   r   s     r    r   zrepo_status.<locals>.<genexpr>   s&      55!*555555r(   c              3  &   K   | ]}|d          V  dS )r   Nr   r   s     r    r   zrepo_status.<locals>.<genexpr>   s&      77A;777777r(   c              3  &   K   | ]}|d          V  dS )r   Nr   r   s     r    r   zrepo_status.<locals>.<genexpr>   s&      99a!L/999999r(      )branchdefaultBranchdetachedaheadbehindr   r   r   r   changedrR   rS   rf   )r5   r!   r>   
startswithrN   r   r   rT   valuessum_UNTRACKED_SCAN_CAPr}   )r
   r$   r6   r&   r   r   r   r   r   r@   tokrf   rR   rS   ars   `               r    repo_statusr      s   3<< tKKKLLLD#qqyytFHEFyy 
/ 
/>>*++ 		/s+,,../D|+H%/TT4FF^^N++ 	/yy{{122 / />>#&& /ABB1--EE^^C(( / QRRA..FNN=;M;MNNNE EGvh''..00  1
1	SnnnnFZGZFZ@[nnnnnnE -c221151111155u55555777777799599999u::tt  r(   scopebase_refc                   t          |           sg ddS |dv r|dk    rt          |           n|}|sg ddS |dk    r| dn|}d t          | |g                                          D             }|dk    r@d |D             t	          | g d	          \  }}}|fd
t          |          D             z  }|                    d            t          | |           ||dS t	          | g d	          \  }}}|dk    rg ddS t          | dg          }	t          | g           }
g }t          |          D ]u\  }}}|	                    |d          \  }}|
                    |d          \  }}|	                    |||z   ||z   t          ||          t          ||          d           v|                    d            t          | |           |ddS )zBChanged files for a scope. Mirrors the Electron reviewList shapes.N)rf   rx   )r   lastTurnr   ...HEADc                *    g | ]\  }\  }}|||d ddS )r   Fr?   rR   rS   ri   r   r   )r   r?   r   r   s       r    r   zreview_list.<locals>.<listcomp>  s>     
 
 
fq! A!seTT
 
 
r(   r   c                    h | ]
}|d          S )r?   r   r   s     r    	<setcomp>zreview_list.<locals>.<setcomp>  s    ---!AfI---r(   ri   r   r   c                <    g | ]\  }}}|d k    |v|ddd ddS )rj   r   Fr   r   )r   r   _xyr?   seens       r    r   zreview_list.<locals>.<listcomp>  sK       "Cd#::$d"2"2 a3RWXX"2"2"2r(   c                    | d         S Nr?   r   r   s    r    <lambda>zreview_list.<locals>.<lambda>  s
    6 r(   )keyr   --cached)r   r   r   c                    | d         S r   r   r   s    r    r   zreview_list.<locals>.<lambda>/  s
    QvY r(   )r5   ry   rT   itemsr!   r   sortrm   getru   r   r   )r
   r   r   rx   rngrf   r&   r6   r$   r   r   r   r   r?   sasruaurr   s                     @r    review_listr     s   3<< +T***&&&$)X$5$5|C   8 	/..."'8"3"3
 
 (se 4 4 : : < <
 
 
 J--u---DS"D"D"DEEIAsA    &3C&8&8   E
 	

**
+++sE***---???@@LD#qqyyT***cJ<((FR  HE&s++ 
 
RD&))BdF++Bb7(b11'R00 	
 	
 	
 	
 
JJ&&J'''3&&&D)))r(   	file_pathr   c                   t          |           sdS |dk    r*t          |           }|rt          | d| dd|g          ndS |dk    r|rt          | d|d|g          ndS |rt          | ddd|g          S t          | dd|g          }|                                r|S t	          | dddt
          j        |g          \  }}}|S )	Nr   r   rH   r   --r   r   
--no-index)r5   ry   r'   r-   r!   rZ   devnull)	r
   r   r   r   r   rx   worktreer&   r%   s	            r    review_diffr   4  s    3<< rC  MQYxf&6&6&6iHIIIWYY
EMUxfhi@AAASUU Dfj$	BCCCfdI677H~~ S6<rz9MNNIAsAJr(   c                <   t          |           sdS t          | ddd|g          }|                                r|S t          | ddd|g          }|                                                    d          sdS t	          | dddt
          j        |g          \  }}}|S )	zWorking-tree-vs-HEAD diff for one file (the preview's diff view). Unlike
    review_diff, never all-adds a clean tracked file; only a genuinely untracked one.r   rH   rt   r   ri   --porcelainr   r   )r5   r'   r-   r   r!   rZ   r   )r
   r   r@   ri   r&   r%   s         r    file_diff_vs_headr   F  s     3<< rC&&$	:;;Dzz|| cHmT9EFFF<<>>$$T** rS6<rz9MNNIAsAJr(   c                <    t          | |rdd|gnddg           ddiS )Naddr   -AokTr0   r
   r   s     r    review_stager   U  s1    CYI%y))UDMJJJ$<r(   c                @    t          | |rdddd|gng d           ddiS )Nreset-qrt   r   )r   r   rt   r   Tr   r   s     r    review_unstager   Z  s8    CYc'4y99LcLcLcddd$<r(   c                n    |rd|gnddg}t          | ddg|           t          | ddg|           ddiS )	zPDiscard changes back to the committed state (restore tracked, remove untracked).r   r   checkoutrt   cleanz-fdr   Tr#   )r
   r   ra   s      r    review_revertr   _  sX    "+<dI$Fz6+F+,,,w''((($<r(   rw   c                V    t          | d|pdg                                          }|pd S )Nrq   rt   )r'   r-   )r
   rw   r%   s      r    review_rev_parser   g  s0    
3cmV4
5
5
;
;
=
=C;$r(   messagepushc                    t          | g d          \  }}}t          d t          |          D                       st          | ddg           t          | dd|g           |rt	          |            ddiS )	zGCommit the working tree; stage everything first when nothing is staged.r   c              3  >   K   | ]\  }}}t          ||          V  d S Nr   r   r   r   r&   s       r    r   z review_commit.<locals>.<genexpr>o  s2      KK*#r1}S"%%KKKKKKr(   r   r   commit-mr   T)r!   anyr   r0   _review_push)r
   r   r   r&   r6   s        r    review_commitr  l  s    S<<<==IAsAKKc8J8JKKKKK $eT]###C(D'*+++ S$<r(   c                    t          | g d                                          }|rt          | dg           d S t          | g d                                          }|r|dk    rt          | ddd|g           d S d S d S )N)rq   rr   z--symbolic-full-namez@{u}r   )rq   rr   rt   rt   z-uorigin)r'   r-   r0   )r
   upstreamr   s      r    r   r   w  s    ZZZ[[aaccH fXc@@@AAGGIIF 7&F""fdHf5666667 7""r(   c                (    t          |            ddiS )Nr   T)r   r4   s    r    review_pushr    s    $<r(   c                   t          |           sdddS t          | g d          \  }}}|dk    rdddS t          t          |                    }t	          d |D                       }|rt          | ddg          nt          | ddg          }t          |          t          k    r,t          |          t          z
  }|d	t                    d
| d}d |D             }|r|d	t                   }	dd	                    d |	D                       z   }
t          |          t          |	          k    r&|
dt          |          t          |	          z
   dz  }
|r| |
 n|
}|pdt          | g d          
                                dS )zJDiff of what WILL commit + recent subjects, for drafting a commit message.r   )rH   recentr   r   c              3  >   K   | ]\  }}}t          ||          V  d S r   r   r   s       r    r   z(review_commit_context.<locals>.<genexpr>  s2      FF
R]3++FFFFFFr(   rH   r   rt   Nz
# diff truncated: z chars omitted
c                &    g | ]\  }}}|d k    |S )rj   r   )r   r   r   r?   s       r    r   z)review_commit_context.<locals>.<listcomp>  s#    BBB.#sDsczzzzzr(   z
# New (untracked) files:
c              3  "   K   | ]
}d | dV  dS )z#   
Nr   )r   ps     r    r   z(review_commit_context.<locals>.<genexpr>  s*      7V7Vq7V7V7V7V7V7Vr(   z#   ... z more omitted
)logz-n10z--pretty=format:%s)r5   r!   listr   r   r'   rN   _COMMIT_CONTEXT_DIFF_MAX_CHARS_COMMIT_CONTEXT_UNTRACKED_MAXr.   r-   )r
   r$   r6   r&   entries
has_stagedrH   omittedr   visiblenotes              r    review_commit_contextr    s   3<< *b)))???@@LD#qqyyb)))=%%&&GFFgFFFFFJ2<a8C&*-...(3QWY_P`BaBaD
4yy111d))<<6667ffWfffBBGBBBI 1:::;-7V7Vg7V7V7V0V0VVy>>CLL((Ms9~~G<MMMMD"&0$DJB(38a8a8a*b*b*h*h*j*jkkkr(   tuple[bool, str]c                    t          j        d          sdS 	 t          j        dg|| ddt                    }n# t
          t          j        f$ r Y dS w xY w|j        dk    |j        pdfS )Ngh)Fr   Tr   r   r   )	shutilwhichr   r   _GH_TIMEOUTr   r   r   r   )r
   r   r   s      r    _ghr    s    < y~MDMs4dK
 
 
 Z/0   yy?a!222s   !: AAc                   t          |           sdddS t          | ddg          \  }}|sdddS t          | g d          \  }}|sdddS 	 t          j        |          }n# t          j        $ r dddcY S w xY w|rJ|                    d          r5d|d         |                    d	          |                    d
          ddS dddS )zPgh availability/auth + this branch's PR. ghReady false when gh missing/unauthed.FN)ghReadyprauthri   )r"  viewz--jsonzurl,state,numberTurlstatenumber)r%  r&  r'  )r5   r  jsonloadsJSONDecodeErrorr   )r
   auth_okr&   view_okr%   r"  s         r    review_ship_infor-    s!   3<< . ---S68,--JGQ . ---sHHHIILGS -t,,,-Z__ - - -t,,,,,-	 qbffUmm qr%y266'??^`^d^dem^n^n'o'oppp4(((s   A# #A:9A:c                .   	 t          |            n# t          $ r Y nw xY wt          | g d          \  }}|st          d          t          d t	          |                                                                          D             d          }d|iS )zLCreate a PR for the current branch (push first), letting gh fill title/body.)r"  createz--fillz8gh pr create failed (is gh installed and authenticated?)c              3  B   K   | ]}|                                 |V  d S r   r-   r   rP   s     r    r   z#review_create_pr.<locals>.<genexpr>  s/      TTtzz||TTTTTTTr(   r   r%  )r   r,   r  nextreversedr-   rM   )r
   createdr%   r%  s       r    review_create_prr6    s    S   s66677LGS WUVVV
TT#))++*@*@*B*B!C!CTTTVX
Y
YC3<s    
r%   c                   g }d }|                      d          D ]}|                    d          r:|r|                    |           |dd                                          d dddd}Q|T|                    d          r5|dd                                                              dd	d
          |d<   |dk    rd|d<   |dk    rd|d<   |                    d          rd|d<   |r|                    |           |S )Nr  z	worktree r   F)r?   r   r   barelockedzbranch    refs/heads/r   r   r   r   Tr8  r9  )r>   r   ru   r-   r=   )r%   treescurrP   s       r    _parse_worktreesr>    s.   EC		$ ! !??;'' 	! "S!!!8>>++tX]inooCC[__Y'' 	! HNN,,44]BJJCMMZ"C
OOV^^CKK__X&& 	! CM
 SLr(   c                z    t          | g d          }|sg S d t          t          |                    D             S )N)r   r  r   c                \    g | ])\  }}|d          |d         |dk    |d         |d         d*S )r?   r   r   r   r9  )r?   r   isMainr   r9  r   )r   indextrees      r    r   z!worktree_list.<locals>.<listcomp>  sY     	 	 	 E4 L8nqjZ(8n	
 	
	 	 	r(   )r'   	enumerater>  )r
   r%   s     r    worktree_listrE    sY    
3;;;
<
<C 		 	 %%5c%:%:;;	 	 	 	r(   c                N    t          |           D ]}|d         r
|d         c S | S )NrA  r?   )rE  )r
   rC  s     r    
_main_rootrG    s?    c""    > 	 <	 Jr(   namec                ,   t          | pd          }t          j        dd|          }t          j        dd|          }t          j        dd|          }t          j        dd|          }t          j        dd	|          }t          j        d
d|          S )Nr   z\s+rK   z[^\w./-]z-{2,}z/{2,}r:   z\.{2,}r   z^[-./]+|[-./]+$)r   resub)rH  values     r    _sanitize_branchrM     s    
OOEF63&&EF;E**EF8S%((EF8S%((EF9c5))E6$b%000r(   c                    t          j        ddt          | pd                                                                                    }t          j        dd|          d d                             d          }|pdS )Nz
[^a-z0-9]+rK   r   z^-+|-+$(   work)rJ  rK  r   r-   lowerrstrip)rH  slugs     r    _slugifyrT  
  sk    6-c$*"oo&;&;&=&=&C&C&E&EFFD6*b$'',33C88D>6r(   c                <   t          | g d                                                              ddd          }|r|S t          | g d                                          }|r|S t          D ].}t          | ddd| g                                          r|c S /dS )	N)zsymbolic-refr|   z--shortzrefs/remotes/origin/HEADzorigin/r   r   )configz--getzinit.defaultBranchzshow-refr{   r;  )r'   r-   r=   _TRUNK_BRANCHES)r
   remote
configuredr   s       r    _default_branchrZ    s    OOO eggggiQ''   #HHHIIOOQQJ !  C*j2H2H2HIJJPPRR 	MMM	2r(   c                    t          | ddg                                          }d}|dk    rt          | dg           d}nt          | g d          \  }}}|dk    }|rt          | g d	           d
S d
S )zA new project folder may not be a repo (or has no commit to branch from);
    init it with a root commit so worktrees just work. No-op for a committed repo.rq   z--is-inside-work-treeFtrueinitT)rq   r{   rt   r   )-czuser.email=hermes@localhostr^  zuser.name=Hermesr   z--allow-emptyr   zInitial commitN)r'   r-   r0   r!   )r
   inside
needs_rootr$   r&   s        r    _ensure_repora    s     cK)@ABBHHJJFJfX

#@@@AA
aQY
 
	 	 		
 	
 	
 	
 	

 
r(   rx   c                    | }d}t           j                            |          r+|dz  }|  d| }t           j                            |          +|S )Nr   rK   )rZ   r?   exists)rx   	candidatens      r    _unique_dirrf  :  sZ    I	A
'..
#
# "	QMMaMM	 '..
#
# " r(   optionsc           	        t          |            t          |           }|pi }t          |                    d          pd          }|                    d          r|st	          d          |t          |          k    rt          |d|g           |||dS t          t          j	        
                    |dt          |                              }t          |dd||g           |||dS t          |                    d	          p(d
t          j        d                                                     }t          |                    d          pd          pd| }t          t          j	        
                    |d|                    }ddd||g}|                    d          r(|                    t          |d                              t!          ||          \  }}	}
|dk    rPd|
pd                                v rt          |dd||g           n#t	          |
                                pd          |||dS )NexistingBranchr   Branch name is required.switch)r?   r   repoRootz
.worktreesr   r   rH  zwork-   r   zhermes/z-brx   r   zalready existszgit worktree add failed)ra  rG  rM  r   r,   rZ  r0   rf  rZ   r?   r.   rT  urandomhexru   r   r!   rQ  r-   )r
   rg  rootexistingra   rS  r   r   r$   r&   r/   s              r    worktree_addrr  C  sA   c??DmG,< = = CDDH{{#$$ F 	;9:::t,,,,D8X./// H$GGGRW\\$hx>P>PQQRRz5&(;<<<(EEEGKK''H+H2:a==3D3D3F3F+H+HIIDgkk(339r::N>N>N>NFdL$??@@FtVV4D{{6 *C(()))d##LD!Sqyy	r002222D:uff=>>>>syy{{G.GHHHf$???r(   worktree_pathforcec                    t          |           }ddg}|r|                    d           |                    |           t          ||           d|iS )Nr   removez--forcerS   )rG  ru   r0   )r
   rs  rt  rp  r   s        r    worktree_removerw  b  s^    c??D!D IKKD$}%%r(   c                    t          | g d          }|sg S t          |           }d |D             t          |           fdd |                    d          D             D             S )N)zfor-each-refz--format=%(refname:short)z--sort=-committerdatez
refs/headsc                <    i | ]}|d          
|d          |d         S )r   r?   r   )r   ts     r    
<dictcomp>zbranch_list.<locals>.<dictcomp>s  s+    KKKq{Kak1V9KKKr(   c                r    g | ]3}|||v t          o|k                                  |          d 4S ))rH  
checkedOut	isDefaultworktreePath)r1   r   )r   rH  path_by_branchtrunks     r    r   zbranch_list.<locals>.<listcomp>u  sh     	 	 	 	.0e566*..t44		
 	
	 	 	r(   c              3  >   K   | ]}|                                 V  d S r   r1  r2  s     r    r   zbranch_list.<locals>.<genexpr>|  s*      >>dTZZ\\>>>>>>r(   r  )r'   rE  rZ  r>   )r
   r%   r<  r  r  s      @@r    branch_listr  l  s    
aaa C  	#EKKeKKKNC  E	 	 	 	 	 ?>ciioo>>>	 	 	 	r(   r   c                n    t          |          }|st          d          t          | d|g           d|iS )Nrj  rk  r   )rM  r,   r0   )r
   r   ra   s      r    branch_switchr    sF    f%%F 75666C(F#$$$fr(   )r
   r   r   r   r	   r   r   r   )r
   r   r   r   r   r   )r
   r   r   r   r   r)   )r
   r   r   r1   )r6   r   r   r   )r
   r   r   r   r   rF   )r
   r   rU   r   r   r   )r
   r   rf   rg   r   r)   )r
   r   r   rn   )r6   r   )r   r   r   r   r   r1   )r   r   r   r   r?   r   r   r   )r   r   r   r   r   r   )r
   r   r   r   )r
   r   r   r   r   rn   r   r   )r
   r   r   r   r   r   r   rn   r   r1   r   r   )r
   r   r   r   r   r   )r
   r   r   rn   r   r   )r
   r   rw   rn   r   rn   )r
   r   r   r   r   r1   r   r   )r
   r   r   r)   )r
   r   r   r   )r
   r   r   r   r   r  )r%   r   r   rg   )r
   r   r   rg   )r
   r   r   r   )rH  r   r   r   )rx   r   r   r   )r
   r   rg  r   r   r   )r
   r   rs  r   rt  r1   r   r   )r
   r   r   r   r   r   );__doc__
__future__r   r(  rZ   rJ  r  r   pathlibr   _GIT_TIMEOUTr  _MAX_BUFFERr]   r   r  r  rW  r!   r'   r0   r5   rE   rT   re   rm   ry   r}   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r  r  r  r-  r6  r>  rE  rG  rM  rT  rZ  ra  rf  rr  rw  r  r  r   r(   r    <module>r     s  
 
 # " " " " "  				 				           '  !(  " $ 7C 5 5 5 5 5 5 $ $ $ $J J J J   * * * *      "E E E E      (   ,9 9 9 9
   2 2 2 20 0 0 0l/* /* /* /*d   $      
   
      
   7 7 7 7   
l l l l:	3 	3 	3 	3) ) ) )&
 
 
 
    .       1 1 1 1      
 
 
 
6   @ @ @ @>& & & &   *     r(   