@@ -1705,6 +1705,9 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
17051705 const formLabelStyle = "block text-sm font-medium text-gray-700 dark:text-gray-300" ;
17061706
17071707 const isGitRepo = formData . vcs === VcsType . Git ;
1708+ const isSvnRepo = formData . vcs === VcsType . Svn ;
1709+ const supportsHistoryTab = isGitRepo || isSvnRepo ;
1710+ const supportsBranchTab = isGitRepo || isSvnRepo ;
17081711 const isGitHubRepo = useMemo ( ( ) => isGitRepo && formData . remoteUrl ?. includes ( 'github.com' ) , [ isGitRepo , formData . remoteUrl ] ) ;
17091712
17101713 // Debounce history search
@@ -1789,7 +1792,7 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
17891792 } , [ selectedBranches , branchInfo ] ) ;
17901793
17911794 const fetchHistory = useCallback ( async ( loadMore = false ) => {
1792- if ( ! repository ) return ;
1795+ if ( ! repository || ! supportsHistoryTab ) return ;
17931796
17941797 if ( loadMore ) {
17951798 setIsMoreHistoryLoading ( true ) ;
@@ -1836,10 +1839,10 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
18361839 setHistoryLoading ( false ) ;
18371840 setIsMoreHistoryLoading ( false ) ;
18381841 }
1839- } , [ repository , setToast , commits . length , debouncedHistorySearch ] ) ;
1842+ } , [ repository , setToast , commits . length , debouncedHistorySearch , supportsHistoryTab ] ) ;
18401843
18411844 const fetchBranches = useCallback ( async ( ) => {
1842- if ( ! repository || ! isGitRepo ) return ;
1845+ if ( ! repository || ! supportsBranchTab ) return ;
18431846 setBranchesLoading ( true ) ;
18441847 try {
18451848 const branches = await window . electronAPI ?. listBranches ( { repoPath : repository . localPath , vcs : repository . vcs } ) ;
@@ -1868,7 +1871,7 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
18681871 } finally {
18691872 setBranchesLoading ( false ) ;
18701873 }
1871- } , [ repository , isGitRepo , setToast ] ) ;
1874+ } , [ repository , supportsBranchTab , setToast ] ) ;
18721875
18731876 const fetchReleases = useCallback ( async ( ) => {
18741877 if ( ! repository || ! isGitHubRepo ) return ;
@@ -1896,7 +1899,7 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
18961899
18971900 // Fetch branch info on mount for the dropdown if possible
18981901 useEffect ( ( ) => {
1899- if ( repository ?. localPath && isGitRepo ) {
1902+ if ( repository ?. localPath && supportsBranchTab ) {
19001903 if ( branchInfo ) return ; // Don't re-fetch if we already have the info.
19011904 const checkPathAndFetch = async ( ) => {
19021905 const pathState = await window . electronAPI ?. checkLocalPath ( repository . localPath ) ;
@@ -1906,13 +1909,13 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
19061909 } ;
19071910 checkPathAndFetch ( ) ;
19081911 }
1909- } , [ repository , isGitRepo , fetchBranches , branchInfo ] ) ;
1912+ } , [ repository , supportsBranchTab , fetchBranches , branchInfo ] ) ;
19101913
19111914 // Fetch data when a tab becomes active or search term changes
19121915 useEffect ( ( ) => {
1913- if ( activeTab === 'history' ) {
1916+ if ( activeTab === 'history' && supportsHistoryTab ) {
19141917 fetchHistory ( false ) ;
1915- } else if ( activeTab === 'branches' ) {
1918+ } else if ( activeTab === 'branches' && supportsBranchTab ) {
19161919 if ( ! branchInfo ) {
19171920 fetchBranches ( ) ;
19181921 }
@@ -2116,6 +2119,10 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
21162119
21172120 const handleCreateBranch = async ( ) => {
21182121 if ( ! repository || ! newBranchName . trim ( ) ) return ;
2122+ if ( ! isGitRepo ) {
2123+ setToast ( { message : 'Branch creation is only supported for Git repositories.' , type : 'info' } ) ;
2124+ return ;
2125+ }
21192126 const result = await window . electronAPI ?. createBranch ( repository . localPath , newBranchName . trim ( ) ) ;
21202127 if ( result ?. success ) {
21212128 setToast ( { message : `Branch '${ newBranchName . trim ( ) } ' created` , type : 'success' } ) ;
@@ -2129,6 +2136,10 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
21292136
21302137 const handleDeleteBranch = async ( branchIdentifier : string , scope : 'local' | 'remote' ) => {
21312138 if ( ! repository ) return ;
2139+ if ( ! isGitRepo ) {
2140+ setToast ( { message : 'Branch deletion is only supported for Git repositories.' , type : 'info' } ) ;
2141+ return ;
2142+ }
21322143 const isRemote = scope === 'remote' ;
21332144 const remoteDetails = isRemote ? parseRemoteBranchIdentifier ( branchIdentifier ) : null ;
21342145 const branchLabel = formatBranchSelectionLabel ( branchIdentifier , scope ) ;
@@ -2173,6 +2184,11 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
21732184 return ;
21742185 }
21752186
2187+ if ( ! isGitRepo ) {
2188+ setToast ( { message : 'Bulk branch deletion is only supported for Git repositories.' , type : 'info' } ) ;
2189+ return ;
2190+ }
2191+
21762192 const currentBranch = branchInfo ?. current ;
21772193 let skippedCurrentCount = 0 ;
21782194 let skippedProtectedCount = 0 ;
@@ -2290,10 +2306,14 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
22902306 }
22912307 }
22922308 } ) ;
2293- } , [ repository , selectedBranches , branchInfo ?. current , confirmAction , setToast , fetchBranches , onRefreshState ] ) ;
2309+ } , [ repository , selectedBranches , branchInfo ?. current , confirmAction , setToast , fetchBranches , onRefreshState , isGitRepo ] ) ;
22942310
22952311 const handleMergeBranch = async ( ) => {
22962312 if ( ! repository || ! branchToMerge ) return ;
2313+ if ( ! isGitRepo ) {
2314+ setToast ( { message : 'Branch merging is only supported for Git repositories.' , type : 'info' } ) ;
2315+ return ;
2316+ }
22972317 const currentBranch = branchInfo ?. current ;
22982318 if ( ! currentBranch || branchToMerge === currentBranch ) {
22992319 setToast ( { message : 'Cannot merge a branch into itself.' , type : 'info' } ) ;
@@ -2626,6 +2646,9 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
26262646 </ div >
26272647 ) ;
26282648 case 'history' :
2649+ if ( ! supportsHistoryTab ) {
2650+ return < div className = "p-4 text-center text-gray-500" > History is only available for Git or SVN repositories.</ div > ;
2651+ }
26292652 return (
26302653 < div className = "p-4 space-y-3 flex flex-col overflow-hidden h-full" >
26312654 < div className = "relative flex-shrink-0" >
@@ -2664,6 +2687,9 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
26642687 </ div >
26652688 ) ;
26662689 case 'branches' : {
2690+ if ( ! supportsBranchTab ) {
2691+ return < div className = "p-4 text-center text-gray-500" > Branch management is only available for Git or SVN repositories.</ div > ;
2692+ }
26672693 const selectedBranchCount = selectedBranches . length ;
26682694 const selectedLocalCount = selectedBranches . filter ( selection => selection . scope === 'local' ) . length ;
26692695 const selectedRemoteCount = selectedBranchCount - selectedLocalCount ;
@@ -2777,7 +2803,7 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
27772803 { isCurrent && < span className = "text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-blue-100 text-blue-700 dark:bg-blue-900/60 dark:text-blue-200" > Current</ span > }
27782804 { isProtectedLocal && < span className = "text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 dark:bg-amber-900/60 dark:text-amber-200" > Protected</ span > }
27792805 </ div >
2780- { ! isCurrent && ! isProtectedLocal && (
2806+ { ! isCurrent && ! isProtectedLocal && isGitRepo && (
27812807 < button
27822808 type = "button"
27832809 onClick = { ( event ) => {
@@ -2818,7 +2844,7 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
28182844 </ span >
28192845 { isProtectedRemote && < span className = "text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 dark:bg-amber-900/60 dark:text-amber-200" > Protected</ span > }
28202846 </ div >
2821- { ! isProtectedRemote && (
2847+ { ! isProtectedRemote && isGitRepo && (
28222848 < button
28232849 type = "button"
28242850 onClick = { ( event ) => {
@@ -2841,15 +2867,17 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
28412867 < div className = "flex flex-wrap items-center justify-between gap-3" >
28422868 < p className = "text-sm text-gray-600 dark:text-gray-300" > { selectionDescription } </ p >
28432869 < div className = "flex flex-wrap items-center gap-2" >
2844- < button
2845- type = "button"
2846- onClick = { handleBulkDeleteSelectedBranches }
2847- disabled = { bulkDeleteDisabled }
2848- title = { bulkDeleteTitle }
2849- className = { `px-4 py-2 rounded-md text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-500 disabled:bg-gray-400 disabled:cursor-not-allowed ${ isDeletingBranches ? 'cursor-wait' : '' } ` }
2850- >
2851- { isDeletingBranches ? 'Deleting…' : 'Delete Selected' }
2852- </ button >
2870+ { isGitRepo && (
2871+ < button
2872+ type = "button"
2873+ onClick = { handleBulkDeleteSelectedBranches }
2874+ disabled = { bulkDeleteDisabled }
2875+ title = { bulkDeleteTitle }
2876+ className = { `px-4 py-2 rounded-md text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-500 disabled:bg-gray-400 disabled:cursor-not-allowed ${ isDeletingBranches ? 'cursor-wait' : '' } ` }
2877+ >
2878+ { isDeletingBranches ? 'Deleting…' : 'Delete Selected' }
2879+ </ button >
2880+ ) }
28532881 < button
28542882 type = "button"
28552883 onClick = { handleCheckoutBranch }
@@ -2860,27 +2888,34 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
28602888 </ button >
28612889 </ div >
28622890 </ div >
2863- < div className = "grid grid-cols-1 md:grid-cols-2 gap-6" >
2864- < div >
2865- < h4 className = "font-semibold mb-2" > Create New Branch</ h4 >
2866- < div className = "flex gap-2" >
2867- < input type = "text" value = { newBranchName } onChange = { e => setNewBranchName ( e . target . value ) } placeholder = "new-branch-name" className = { formInputStyle } />
2868- < button type = "button" onClick = { handleCreateBranch } className = "px-4 py-2 bg-green-600 text-white rounded-md text-sm font-medium hover:bg-green-700" > Create</ button >
2891+ { isSvnRepo && (
2892+ < p className = "text-xs text-gray-500 dark:text-gray-400" >
2893+ Branch creation, deletion, and merging are currently only available for Git repositories.
2894+ </ p >
2895+ ) }
2896+ { isGitRepo && (
2897+ < div className = "grid grid-cols-1 md:grid-cols-2 gap-6" >
2898+ < div >
2899+ < h4 className = "font-semibold mb-2" > Create New Branch</ h4 >
2900+ < div className = "flex gap-2" >
2901+ < input type = "text" value = { newBranchName } onChange = { e => setNewBranchName ( e . target . value ) } placeholder = "new-branch-name" className = { formInputStyle } />
2902+ < button type = "button" onClick = { handleCreateBranch } className = "px-4 py-2 bg-green-600 text-white rounded-md text-sm font-medium hover:bg-green-700" > Create</ button >
2903+ </ div >
28692904 </ div >
2870- </ div >
2871- < div >
2872- < h4 className = "font-semibold mb -2" > Merge Branch into Current </ h4 >
2873- < div className = "flex gap-2" >
2874- < select value = { branchToMerge || '' } onChange = { e => setBranchToMerge ( e . target . value ) } className = { formInputStyle } >
2875- < option value = "" disabled > Select a branch </ option >
2876- { ( branchInfo ?. local || [ ] ) . filter ( b => b !== branchInfo ?. current ) . map ( b => (
2877- < option key = { b } value = { b } > { b } </ option >
2878- ) ) }
2879- </ select >
2880- < button type = "button" onClick = { handleMergeBranch } className = "px-4 py-2 bg-indigo-600 text-white rounded-md text-sm font-medium hover:bg-indigo-700" > Merge </ button >
2905+ < div >
2906+ < h4 className = "font-semibold mb-2" > Merge Branch into Current </ h4 >
2907+ < div className = "flex gap -2" >
2908+ < select value = { branchToMerge || '' } onChange = { e => setBranchToMerge ( e . target . value ) } className = { formInputStyle } >
2909+ < option value = "" disabled > Select a branch </ option >
2910+ { ( branchInfo ?. local || [ ] ) . filter ( b => b !== branchInfo ?. current ) . map ( b => (
2911+ < option key = { b } value = { b } > { b } </ option >
2912+ ) ) }
2913+ </ select >
2914+ < button type = "button" onClick = { handleMergeBranch } className = "px-4 py-2 bg-indigo-600 text-white rounded-md text-sm font-medium hover:bg-indigo-700" > Merge </ button >
2915+ </ div >
28812916 </ div >
28822917 </ div >
2883- </ div >
2918+ ) }
28842919 </ div >
28852920 </ div >
28862921 ) }
@@ -3214,8 +3249,8 @@ const RepoEditView: React.FC<RepoEditViewProps> = ({ onSave, onCancel, repositor
32143249 < div className = "flex-shrink-0 border-b border-gray-200 dark:border-gray-700" >
32153250 < nav className = "-mb-px flex space-x-4 px-4" >
32163251 < button onClick = { ( ) => setActiveTab ( 'tasks' ) } className = { `whitespace-nowrap py-3 px-1 border-b-2 font-medium text-sm ${ activeTab === 'tasks' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' } ` } > Tasks</ button >
3217- { isGitRepo && < button onClick = { ( ) => setActiveTab ( 'history' ) } className = { `whitespace-nowrap py-3 px-1 border-b-2 font-medium text-sm ${ activeTab === 'history' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' } ` } > History</ button > }
3218- { isGitRepo && < button onClick = { ( ) => setActiveTab ( 'branches' ) } className = { `whitespace-nowrap py-3 px-1 border-b-2 font-medium text-sm ${ activeTab === 'branches' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' } ` } > Branches</ button > }
3252+ { supportsHistoryTab && < button onClick = { ( ) => setActiveTab ( 'history' ) } className = { `whitespace-nowrap py-3 px-1 border-b-2 font-medium text-sm ${ activeTab === 'history' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' } ` } > History</ button > }
3253+ { supportsBranchTab && < button onClick = { ( ) => setActiveTab ( 'branches' ) } className = { `whitespace-nowrap py-3 px-1 border-b-2 font-medium text-sm ${ activeTab === 'branches' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' } ` } > Branches</ button > }
32193254 { isGitRepo && < button onClick = { ( ) => setActiveTab ( 'releases' ) } className = { `whitespace-nowrap py-3 px-1 border-b-2 font-medium text-sm ${ activeTab === 'releases' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' } ` } > Releases</ button > }
32203255 </ nav >
32213256 </ div >
0 commit comments