23 KiB
Duplicate Methods Analysis Report - gui/main_window.py
Overview
This report analyzes the duplicate methods found in gui/main_window.py to determine their differences and whether they can be safely consolidated.
1. manage_branches (line 1374 vs line 2336)
First Version (line 1374-1377)
def manage_branches(self, project):
"""Manage git branches"""
messagebox.showinfo("Branches", "Branch management coming soon")
Second Version (line 2336-2391)
def manage_branches(self, project):
"""Manage branches for a project"""
from tkinter import simpledialog
git_ops = self.repo_manager.git_ops
# Get current branches
success, branches = git_ops.branch(Path(project.path), list_all=True)
if success:
current_branch = None
branch_list = []
for line in branches.strip().split('\n'):
if line.startswith('*'):
current_branch = line[2:].strip()
branch_list.append(f"{line.strip()} (aktuell)")
else:
branch_list.append(line.strip())
# Show options
action = messagebox.askyesnocancel(
"Branch-Verwaltung",
f"Aktuelle Branches:\n{chr(10).join(branch_list)}\n\n"
"Ja = Neuen Branch erstellen\n"
"Nein = Zu anderem Branch wechseln\n"
"Abbrechen = Schließen"
)
if action is True: # Create new branch
branch_name = simpledialog.askstring(
"Neuer Branch",
"Name des neuen Branches:",
parent=self.root
)
if branch_name:
success, result = git_ops.checkout(Path(project.path), branch_name, create=True)
if success:
messagebox.showinfo("Erfolg", f"Branch '{branch_name}' erstellt und gewechselt")
else:
messagebox.showerror("Fehler", f"Branch-Erstellung fehlgeschlagen: {result}")
elif action is False: # Switch branch
branch_name = simpledialog.askstring(
"Branch wechseln",
"Zu welchem Branch wechseln?",
parent=self.root
)
if branch_name:
success, result = git_ops.checkout(Path(project.path), branch_name)
if success:
messagebox.showinfo("Erfolg", f"Zu Branch '{branch_name}' gewechselt")
else:
messagebox.showerror("Fehler", f"Branch-Wechsel fehlgeschlagen: {result}")
else:
messagebox.showerror("Fehler", f"Konnte Branches nicht abrufen: {branches}")
Differences
- First version: Placeholder implementation showing "coming soon" message
- Second version: Full implementation with branch listing, creation, and switching functionality
- Language: First version uses English, second version uses German
Called From
- Line 1516:
self.manage_branches(project)ingitea_operationmethod
Recommendation
Safe to consolidate: Keep the second version (line 2336) as it contains the actual implementation. The first version is just a placeholder.
2. link_to_gitea (line 1378 vs line 2392)
First Version (line 1378-1381)
def link_to_gitea(self, project):
"""Link local project to Gitea repository"""
messagebox.showinfo("Link", "Link functionality coming soon")
Second Version (line 2392-2456)
def link_to_gitea(self, project):
"""Link local project to Gitea repository"""
from tkinter import simpledialog
# Ask for repository name
repo_name = simpledialog.askstring(
"Mit Gitea verknüpfen",
"Name des Gitea-Repositories:",
initialvalue=project.name,
parent=self.root
)
if repo_name:
git_ops = self.repo_manager.git_ops
# Check if repo exists on Gitea
try:
repo = self.repo_manager.client.get_repository(
self.repo_manager.client.config.username,
repo_name
)
# Add remote
success, msg = git_ops.add_remote_to_existing_repo(
Path(project.path),
self.repo_manager.client.config.username,
repo_name
)
if success:
# Update project with Gitea repo reference
project.gitea_repo = f"{self.repo_manager.client.config.username}/{repo_name}"
self.project_manager.update_project(project.id, gitea_repo=project.gitea_repo)
messagebox.showinfo("Erfolg", f"Erfolgreich mit Repository '{repo_name}' verknüpft!")
else:
messagebox.showerror("Fehler", f"Verknüpfung fehlgeschlagen: {msg}")
except Exception as e:
# Repository doesn't exist, offer to create
create = messagebox.askyesno(
"Repository nicht gefunden",
f"Repository '{repo_name}' existiert nicht.\n\nMöchten Sie es erstellen?"
)
if create:
try:
# Create repository
new_repo = self.repo_manager.create_repository(repo_name, auto_init=False)
# Add remote
success, msg = git_ops.add_remote_to_existing_repo(
Path(project.path),
self.repo_manager.client.config.username,
repo_name
)
if success:
# Update project
project.gitea_repo = f"{self.repo_manager.client.config.username}/{repo_name}"
self.project_manager.update_project(project.id, gitea_repo=project.gitea_repo)
messagebox.showinfo("Erfolg",
f"Repository '{repo_name}' erstellt und verknüpft!")
else:
messagebox.showerror("Fehler", f"Verknüpfung fehlgeschlagen: {msg}")
except Exception as create_error:
messagebox.showerror("Fehler",
f"Repository-Erstellung fehlgeschlagen: {str(create_error)}")
Differences
- First version: Placeholder implementation showing "coming soon" message
- Second version: Full implementation with repository linking, checking existence, and creation option
- Language: First version uses English, second version uses German
Called From
- Line 1514:
self.link_to_gitea(project)ingitea_operationmethod
Recommendation
Safe to consolidate: Keep the second version (line 2392) as it contains the actual implementation. The first version is just a placeholder.
3. test_gitea_connection (line 1757 vs line 2457)
First Version (line 1757-1791)
def test_gitea_connection(self, project):
"""Test Gitea connection and show permissions"""
try:
# Test API connection
user_info = self.repo_manager.client.get_user_info()
info = "Gitea-Verbindung erfolgreich!\n\n"
info += f"Benutzer: {user_info.get('username', 'Unknown')}\n"
info += f"E-Mail: {user_info.get('email', 'Unknown')}\n"
info += f"Admin: {'Ja' if user_info.get('is_admin', False) else 'Nein'}\n\n"
# Check organizations
orgs = self.repo_manager.client.list_user_organizations()
if orgs:
info += "Organisationen:\n"
for org in orgs:
org_name = org.get('username', org.get('name', 'Unknown'))
info += f" • {org_name}"
# Check teams/permissions in org
teams = self.repo_manager.client.get_user_teams_in_org(org_name)
if teams:
team_names = [t.get('name', 'Unknown') for t in teams]
info += f" (Teams: {', '.join(team_names)})"
info += "\n"
else:
info += "Keine Organisationen\n"
info += f"\nServer: {self.repo_manager.client.config.base_url}"
messagebox.showinfo("Verbindungstest", info)
except Exception as e:
messagebox.showerror("Verbindungsfehler", f"Konnte keine Verbindung zu Gitea herstellen:\n\n{str(e)}")
Second Version (line 2457-2554)
def test_gitea_connection(self, project=None):
"""Test Gitea connection and show detailed information"""
try:
# Test basic connection
user_info = self.repo_manager.client.get_user_info()
username = user_info.get('username', 'Unknown')
# Get organizations
orgs = self.repo_manager.client.list_user_organizations()
org_names = [org['username'] for org in orgs]
# Build info message
info = f"✅ Gitea Verbindung erfolgreich!\n\n"
info += f"Benutzer: {username}\n"
info += f"Server: {self.repo_manager.client.config.base_url}\n"
info += f"Organisationen: {', '.join(org_names) if org_names else 'Keine'}\n\n"
# Check organization permissions if in org mode
if hasattr(self, 'gitea_explorer') and self.gitea_explorer.view_mode == "organization":
org_name = self.gitea_explorer.organization_name
if org_name:
teams = self.repo_manager.client.get_user_teams_in_org(org_name)
if teams:
info += f"Teams in {org_name}:\n"
for team in teams:
info += f" - {team.get('name', 'Unknown')} "
perms = []
if team.get('can_create_org_repo'):
perms.append("kann Repos erstellen")
if team.get('permission') == 'admin':
perms.append("Admin")
elif team.get('permission') == 'write':
perms.append("Schreiben")
elif team.get('permission') == 'read':
perms.append("Lesen")
info += f"({', '.join(perms) if perms else 'keine Rechte'})\n"
else:
info += f"⚠️ Keine Teams in Organisation {org_name} gefunden!\n"
info += "Dies könnte der Grund sein, warum Repositories nicht erstellt werden können.\n"
info += "\n"
# If we have a project, show its remote info
if project:
project_path = Path(project.path) if hasattr(project, 'path') else Path(project['path'])
if project_path.exists():
success, remotes = self.repo_manager.git_ops.remote_list(project_path)
if success and remotes:
info += f"Git Remote URLs:\n{remotes}\n\n"
# Check if .git exists
if (project_path / '.git').exists():
# Get current branch
success, branch_out = self.repo_manager.git_ops._run_git_command(
["git", "branch", "--show-current"], cwd=project_path
)
if success:
info += f"Aktueller Branch: {branch_out.strip()}\n"
# List repositories in current mode
info += "Repositories:\n"
try:
if hasattr(self, 'gitea_explorer'):
if self.gitea_explorer.view_mode == "organization" and self.gitea_explorer.organization_name:
# List org repos
org_repos = self.repo_manager.list_organization_repositories(self.gitea_explorer.organization_name)
info += f"In Organisation {self.gitea_explorer.organization_name}: {len(org_repos)} Repositories\n"
for repo in org_repos[:5]: # Show first 5
info += f" - {repo['name']}\n"
if len(org_repos) > 5:
info += f" ... und {len(org_repos) - 5} weitere\n"
else:
# List user repos
user_repos = self.repo_manager.list_all_repositories()
info += f"Benutzer Repositories: {len(user_repos)}\n"
for repo in user_repos[:5]: # Show first 5
info += f" - {repo['name']} (Owner: {repo.get('owner', {}).get('username', 'Unknown')})\n"
if len(user_repos) > 5:
info += f" ... und {len(user_repos) - 5} weitere\n"
except Exception as e:
info += f"Fehler beim Abrufen der Repositories: {str(e)}\n"
# Show log file location
log_file = Path.home() / ".claude_project_manager" / "gitea_operations.log"
info += f"\nLog-Datei: {log_file}"
messagebox.showinfo("Gitea Verbindungstest", info)
except Exception as e:
error_msg = f"❌ Gitea Verbindung fehlgeschlagen!\n\n"
error_msg += f"Fehler: {str(e)}\n\n"
error_msg += f"Server: {self.repo_manager.client.config.base_url}\n"
error_msg += "\nBitte prüfen Sie:\n"
error_msg += "- Netzwerkverbindung\n"
error_msg += "- API Token Gültigkeit\n"
error_msg += "- Server Erreichbarkeit"
messagebox.showerror("Gitea Verbindungstest", error_msg)
Key Differences
- Parameter: First version requires
project, second version hasproject=None(optional) - Detail level: Second version shows much more information including:
- Team permissions with detailed permission levels
- Project-specific git remote info if project is provided
- Current branch information
- Repository listings (user/org mode aware)
- Log file location
- UI elements: First version shows email and admin status, second version doesn't
- Error handling: Second version has more detailed error messages with checkmark/cross emojis
Called From
- Line 1522:
self.test_gitea_connection(project)ingitea_operationmethod
Recommendation
Requires careful consolidation: The second version is more comprehensive but has an optional parameter. Since the call from gitea_operation always passes a project, we should keep the enhanced functionality of the second version but ensure it works correctly when a project is provided.
4. verify_repository_on_gitea (line 1792 vs line 2556)
First Version (line 1792-1849+)
def verify_repository_on_gitea(self, project):
"""Verify if repository exists on Gitea and show detailed info"""
import re
from pathlib import Path
project_path = Path(project.path)
# Check if it's a git repo
if not (project_path / ".git").exists():
messagebox.showinfo("Info", "Dies ist kein Git-Repository.")
return
# Get remote info
git_ops = self.repo_manager.git_ops
success, remotes = git_ops.remote_list(project_path)
if not success or not remotes:
messagebox.showinfo("Info", "Kein Remote-Repository konfiguriert.")
return
# Extract owner and repo name from remote URL
match = re.search(r'gitea-undso\.intelsight\.de[:/]([^/]+)/([^/\.]+)', remotes)
if not match:
messagebox.showwarning("Warnung", f"Konnte Repository-Info nicht aus Remote-URL extrahieren:\n{remotes}")
return
remote_owner = match.group(1)
remote_repo = match.group(2)
info = f"Suche Repository: {remote_owner}/{remote_repo}\n\n"
# Check if repo exists under detected owner
try:
repo = self.repo_manager.client.get_repository(remote_owner, remote_repo)
info += "✅ Repository gefunden!\n\n"
info += f"Name: {repo.get('name', 'Unknown')}\n"
info += f"Owner: {repo.get('owner', {}).get('username', 'Unknown')}\n"
info += f"URL: {repo.get('html_url', 'Unknown')}\n"
info += f"Clone URL: {repo.get('clone_url', 'Unknown')}\n"
info += f"Privat: {'Ja' if repo.get('private', False) else 'Nein'}\n"
info += f"Größe: {repo.get('size', 0) / 1024:.1f} KB\n"
info += f"Default Branch: {repo.get('default_branch', 'Keiner')}\n"
info += f"Erstellt: {repo.get('created_at', 'Unknown')}\n"
info += f"Zuletzt aktualisiert: {repo.get('updated_at', 'Unknown')}\n"
# Check for content
has_content = repo.get('size', 0) > 0 or repo.get('default_branch')
if not has_content:
info += "\n⚠️ WARNUNG: Repository scheint leer zu sein!\n"
except Exception as e:
info += f"❌ Repository nicht unter {remote_owner}/{remote_repo} gefunden!\n"
info += f"Fehler: {str(e)}\n\n"
# Search in all locations
info += "Suche in allen verfügbaren Orten:\n\n"
# Check user repos
# ... (continues beyond visible range)
Second Version (line 2556-2656)
def verify_repository_on_gitea(self, project):
"""Verify if repository exists on Gitea and show detailed info"""
project_name = project.name if hasattr(project, 'name') else project.get('name', 'Unknown')
project_path = Path(project.path) if hasattr(project, 'path') else Path(project['path'])
info = f"Repository Verifizierung für: {project_name}\n"
info += "=" * 50 + "\n\n"
# Check git remotes
git_ops = self.repo_manager.git_ops
success, remotes = git_ops.remote_list(project_path)
if success and remotes:
info += f"Git Remote URLs:\n{remotes}\n\n"
# Extract repo name and owner from remote
import re
match = re.search(r'gitea-undso\.intelsight\.de[:/]([^/]+)/([^/\.]+)', remotes)
if match:
remote_owner = match.group(1)
remote_repo = match.group(2)
info += f"Remote zeigt auf: {remote_owner}/{remote_repo}\n\n"
# Search for repository
info += "Suche Repository auf Gitea:\n"
# 1. Check exact location
try:
repo = self.repo_manager.client.get_repository(remote_owner, remote_repo)
info += f"✅ Gefunden unter {remote_owner}/{remote_repo}\n"
info += f" URL: {repo.get('html_url', 'Unknown')}\n"
info += f" Größe: {repo.get('size', 0)} bytes\n"
info += f" Erstellt: {repo.get('created_at', 'Unknown')}\n"
info += f" Aktualisiert: {repo.get('updated_at', 'Unknown')}\n"
info += f" Default Branch: {repo.get('default_branch', 'Unknown')}\n"
info += f" Privat: {'Ja' if repo.get('private') else 'Nein'}\n"
except Exception as e:
info += f"❌ Nicht gefunden unter {remote_owner}/{remote_repo}\n"
info += f" Fehler: {str(e)}\n"
# 2. Search in all user repos
info += "\nSuche in allen Benutzer-Repositories:\n"
try:
user_repos = self.repo_manager.list_all_repositories()
matching_repos = [r for r in user_repos if r['name'] == remote_repo or r['name'] == project_name]
if matching_repos:
for repo in matching_repos:
info += f"✅ Gefunden: {repo['owner']['username']}/{repo['name']}\n"
info += f" URL: {repo.get('html_url', 'Unknown')}\n"
else:
info += "❌ Nicht in Benutzer-Repositories gefunden\n"
except Exception as e:
info += f"❌ Fehler beim Durchsuchen: {str(e)}\n"
# 3. Search in organization
if hasattr(self, 'gitea_explorer') and self.gitea_explorer.organization_name:
info += f"\nSuche in Organisation {self.gitea_explorer.organization_name}:\n"
try:
org_repos = self.repo_manager.list_organization_repositories(self.gitea_explorer.organization_name)
matching_repos = [r for r in org_repos if r['name'] == remote_repo or r['name'] == project_name]
if matching_repos:
for repo in matching_repos:
info += f"✅ Gefunden: {repo['name']}\n"
info += f" URL: {repo.get('html_url', 'Unknown')}\n"
else:
info += "❌ Nicht in Organisation gefunden\n"
except Exception as e:
info += f"❌ Fehler beim Durchsuchen: {str(e)}\n"
else:
info += "❌ Keine Git Remote gefunden!\n"
# Check for debug file
debug_file = project_path / "gitea_push_debug.txt"
if debug_file.exists():
info += f"\n\n📄 Debug-Datei gefunden: {debug_file}\n"
try:
with open(debug_file, 'r', encoding='utf-8') as f:
debug_content = f.read()
info += "Debug-Inhalt:\n" + "-" * 30 + "\n"
info += debug_content[:1000] # First 1000 chars
if len(debug_content) > 1000:
info += "\n... (gekürzt)"
except:
info += "Konnte Debug-Datei nicht lesen\n"
# Show in scrollable dialog
dialog = ctk.CTkToplevel(self.root)
dialog.title("Repository Verifizierung")
dialog.geometry("800x600")
text_widget = ctk.CTkTextbox(dialog, wrap="word")
text_widget.pack(fill="both", expand=True, padx=10, pady=10)
text_widget.insert("1.0", info)
text_widget.configure(state="disabled")
close_btn = ctk.CTkButton(
dialog,
text="Schließen",
command=dialog.destroy
)
close_btn.pack(pady=10)
Key Differences
- Project access: Second version handles both object attributes and dictionary access for project data
- Pre-checks: First version checks if it's a git repo and has remotes before proceeding
- Display method: First version shows info in messagebox, second version uses a scrollable CTkToplevel dialog
- Additional features: Second version includes:
- Debug file checking and display
- More structured repository search (exact location, user repos, org repos)
- Header with project name
- Size display: First version shows size in KB, second version in bytes
Called From
- Line 1524:
self.verify_repository_on_gitea(project)ingitea_operationmethod - Line 1987:
self.verify_repository_on_gitea(project)infix_repository_issuesmethod (nested functioncheck_on_gitea)
Recommendation
Requires careful consolidation: Both versions have valuable features. The second version's scrollable dialog is better for displaying detailed information, but the first version's pre-checks are important. Combine both:
- Keep pre-checks from first version
- Keep the enhanced display and debug file checking from second version
- Ensure consistent project data access
Summary and Recommendations
manage_branches: Delete first version (placeholder), keep second versionlink_to_gitea: Delete first version (placeholder), keep second versiontest_gitea_connection: Merge both versions, keeping the enhanced functionality of the second while ensuring it works with required project parameterverify_repository_on_gitea: Merge both versions, combining pre-checks from first with enhanced display from second
All duplicates are called from the same gitea_operation method, so consolidation is safe. The first versions of manage_branches and link_to_gitea are just placeholders that were later implemented fully in the second versions.