From 20ff5c822b5663258616fa152f8fc29ad2c1318c Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Sat, 7 Sep 2024 15:17:47 +0930 Subject: [PATCH] fix: fix checkout / delete branches --- backend/app/git/branches/create.py | 17 +++++-------- backend/app/git/branches/delete.py | 37 ++++++++++++++++++----------- backend/app/git/branches/get.py | 35 +++++++++++++++++---------- backend/app/git/branches/manager.py | 6 ++++- 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/backend/app/git/branches/create.py b/backend/app/git/branches/create.py index 479e940..9134cda 100644 --- a/backend/app/git/branches/create.py +++ b/backend/app/git/branches/create.py @@ -1,5 +1,4 @@ # git/branches/create.py - import git import logging @@ -9,21 +8,17 @@ def create_branch(repo_path, branch_name, base_branch='main'): try: logger.debug(f"Attempting to create branch {branch_name} from {base_branch}") repo = git.Repo(repo_path) - + # Check if the branch already exists if branch_name in repo.heads: return False, f"Branch '{branch_name}' already exists." - + # Create and checkout the new branch new_branch = repo.create_head(branch_name, commit=base_branch) new_branch.checkout() - - # Push the new branch to remote and set the upstream branch - origin = repo.remote(name='origin') - origin.push(refspec=f"{branch_name}:{branch_name}", set_upstream=True) - - logger.debug(f"Successfully created and pushed branch: {branch_name}") - return True, {"message": f"Created and set upstream for branch: {branch_name}", "current_branch": branch_name} + + logger.debug(f"Successfully created branch: {branch_name}") + return True, {"message": f"Created branch: {branch_name}", "current_branch": branch_name} except Exception as e: logger.error(f"Error creating branch: {str(e)}", exc_info=True) - return False, {"error": f"Error creating branch: {str(e)}"} \ No newline at end of file + return False, {"error": f"Error creating branch: {str(e)}"} diff --git a/backend/app/git/branches/delete.py b/backend/app/git/branches/delete.py index 914988b..74fc5ea 100644 --- a/backend/app/git/branches/delete.py +++ b/backend/app/git/branches/delete.py @@ -5,31 +5,40 @@ from git.exc import GitCommandError import logging logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) def delete_branch(repo_path, branch_name): try: logger.debug(f"Attempting to delete branch: {branch_name}") + logger.debug(f"Attempting to delete branch from repo at path: {repo_path}") repo = git.Repo(repo_path) - # Check if the branch exists - if branch_name not in repo.heads: - return False, f"Branch '{branch_name}' does not exist." + # Fetch updates from remote + logger.debug("Fetching updates from remote...") + repo.git.fetch('--all') - # Check if it's the current branch - if repo.active_branch.name == branch_name: - return False, f"Cannot delete the current branch: {branch_name}" + # Update local repository state + logger.debug("Updating local repository state...") + repo.git.remote('update', 'origin', '--prune') - # Delete the branch locally - repo.delete_head(branch_name, force=True) + # Check if it's a local branch + if branch_name in repo.heads: + logger.debug(f"Deleting local branch: {branch_name}") + if repo.active_branch.name == branch_name: + return False, f"Cannot delete the current branch: {branch_name}" + repo.delete_head(branch_name, force=True) + logger.debug(f"Local branch {branch_name} deleted") - # Delete the branch remotely + # Attempt to delete remote branch try: + logger.debug(f"Attempting to delete remote branch: {branch_name}") repo.git.push('origin', '--delete', branch_name) - except GitCommandError: - logger.warning(f"Failed to delete remote branch: {branch_name}. It may not exist on remote.") + logger.debug(f"Successfully deleted remote branch: {branch_name}") + return True, {"message": f"Deleted branch: {branch_name}", "current_branch": repo.active_branch.name} + except git.GitCommandError as e: + logger.error(f"Failed to delete remote branch: {branch_name}. Error: {str(e)}") + return False, f"Failed to delete remote branch: {branch_name}. It may not exist or there might be permission issues." - logger.debug(f"Successfully deleted branch: {branch_name}") - return True, {"message": f"Deleted branch: {branch_name}", "current_branch": repo.active_branch.name} except Exception as e: logger.error(f"Error deleting branch: {str(e)}", exc_info=True) - return False, {"error": f"Error deleting branch: {str(e)}"} \ No newline at end of file + return False, {"error": f"Error deleting branch: {str(e)}"} diff --git a/backend/app/git/branches/get.py b/backend/app/git/branches/get.py index 8d8a130..94bd534 100644 --- a/backend/app/git/branches/get.py +++ b/backend/app/git/branches/get.py @@ -1,5 +1,3 @@ -# git/branches/get.py - import git import logging from flask import Blueprint, jsonify @@ -12,20 +10,29 @@ def get_branches(repo_path): repo = git.Repo(repo_path) # Get local branches - local_branches = [{'name': branch.name} for branch in repo.heads] - + local_branches = [{'name': branch.name, 'isLocal': True, 'isRemote': False} for branch in repo.heads] + logger.debug(f"Local branches found: {[branch['name'] for branch in local_branches]}") + # Get remote branches - remote_branches = [{'name': ref.remote_head} for ref in repo.remote().refs] + remote_branches = [{'name': ref.remote_head, 'isLocal': False, 'isRemote': True} for ref in repo.remote().refs if not ref.remote_head == 'HEAD'] + logger.debug(f"Remote branches found: {[branch['name'] for branch in remote_branches]}") - # Combine and remove duplicates, and exclude 'HEAD' - all_branches = {branch['name']: branch for branch in local_branches + remote_branches if branch['name'] != 'HEAD'}.values() + # Combine and update status for branches that are both local and remote + all_branches = local_branches + remote_branches + branch_dict = {} + for branch in all_branches: + if branch['name'] in branch_dict: + branch_dict[branch['name']]['isLocal'] = branch_dict[branch['name']]['isLocal'] or branch['isLocal'] + branch_dict[branch['name']]['isRemote'] = branch_dict[branch['name']]['isRemote'] or branch['isRemote'] + else: + branch_dict[branch['name']] = branch + + all_branches = list(branch_dict.values()) - logger.debug(f"Successfully retrieved branches: {[branch['name'] for branch in all_branches]}") - - # Log the branches before sending + logger.debug(f"All branches combined (local and remote): {[branch['name'] for branch in all_branches]}") logger.info(f"Branches being sent: {[branch['name'] for branch in all_branches]}") - return True, {"branches": list(all_branches)} + return True, {"branches": all_branches} except Exception as e: logger.error(f"Error getting branches: {str(e)}", exc_info=True) return False, {"error": f"Error getting branches: {str(e)}"} @@ -33,7 +40,9 @@ def get_branches(repo_path): def get_current_branch(repo_path): try: repo = git.Repo(repo_path) - return repo.active_branch.name + current_branch = repo.active_branch.name + logger.debug(f"Current branch: {current_branch}") + return current_branch except Exception as e: logger.error(f"Error getting current branch: {str(e)}", exc_info=True) - return None \ No newline at end of file + return None diff --git a/backend/app/git/branches/manager.py b/backend/app/git/branches/manager.py index dd020a0..cf95482 100644 --- a/backend/app/git/branches/manager.py +++ b/backend/app/git/branches/manager.py @@ -5,6 +5,7 @@ from .create import create_branch from .checkout import checkout_branch from .delete import delete_branch from .get import get_branches, get_current_branch +from .push import push_branch_to_remote class Branch_Manager: def __init__(self, repo_path): @@ -23,4 +24,7 @@ class Branch_Manager: return get_branches(self.repo_path) def get_current(self): - return get_current_branch(self.repo_path) \ No newline at end of file + return get_current_branch(self.repo_path) + + def push(self, branch_name): + return push_branch_to_remote(self.repo_path, branch_name) \ No newline at end of file