From 041f4e4bb567198dbcc1c3506abd3d513c88a798 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Sat, 11 Jan 2025 09:37:22 +0900 Subject: [PATCH] fixed: robust branch switching for git repo https://github.com/ltdrdata/ComfyUI-Manager/issues/1410 --- git_helper.py | 35 ++++++++++++++++-- glob/manager_core.py | 81 +++++++++++++++++++++++++++++++++--------- glob/manager_server.py | 16 ++++----- pyproject.toml | 2 +- 4 files changed, 105 insertions(+), 29 deletions(-) diff --git a/git_helper.py b/git_helper.py index 14c6b7e9..6a41f0b9 100644 --- a/git_helper.py +++ b/git_helper.py @@ -124,18 +124,47 @@ def gitcheck(path, do_fetch=False): print("CUSTOM NODE CHECK: Error") +def get_remote_name(repo): + available_remotes = [remote.name for remote in repo.remotes] + if 'origin' in available_remotes: + return 'origin' + elif 'upstream' in available_remotes: + return 'upstream' + elif len(available_remotes) > 0: + return available_remotes[0] + + if not available_remotes: + print(f"[ComfyUI-Manager] No remotes are configured for this repository: {repo.working_dir}") + else: + print(f"[ComfyUI-Manager] Available remotes in '{repo.working_dir}': ") + for remote in available_remotes: + print(f"- {remote}") + + return None + + def switch_to_default_branch(repo): + remote_name = get_remote_name(repo) + try: - default_branch = repo.git.symbolic_ref('refs/remotes/origin/HEAD').replace('refs/remotes/origin/', '') + if remote_name is None: + return False + + default_branch = repo.git.symbolic_ref(f'refs/remotes/{remote_name}/HEAD').replace(f'refs/remotes/{remote_name}/', '') repo.git.checkout(default_branch) + return True except: try: repo.git.checkout(repo.heads.master) except: try: - repo.git.checkout('-b', 'master', 'origin/master') + if remote_name is not None: + repo.git.checkout('-b', 'master', f'{remote_name}/master') except: - print("[ComfyUI Manager] Failed to switch to the default branch") + pass + + print("[ComfyUI Manager] Failed to switch to the default branch") + return False def gitpull(path): diff --git a/glob/manager_core.py b/glob/manager_core.py index 1ff608e9..294f38b8 100644 --- a/glob/manager_core.py +++ b/glob/manager_core.py @@ -41,7 +41,7 @@ import manager_downloader from node_package import InstalledNodePackage -version_code = [3, 5, 1] +version_code = [3, 6] version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') @@ -1227,16 +1227,21 @@ class UnifiedManager: repo = git.Repo(repo_path) if repo.head.is_detached: - switch_to_default_branch(repo) + if not switch_to_default_branch(repo): + return result.fail(f"Failed to switch to default branch: {repo_path}") current_branch = repo.active_branch branch_name = current_branch.name if current_branch.tracking_branch() is None: print(f"[ComfyUI-Manager] There is no tracking branch ({current_branch})") - remote_name = 'origin' + remote_name = get_remote_name(repo) else: remote_name = current_branch.tracking_branch().remote_name + + if remote_name is None: + return result.fail(f"Failed to get remote when installing: {repo_path}") + remote = repo.remote(name=remote_name) try: @@ -1586,18 +1591,47 @@ def get_config(): return cached_config +def get_remote_name(repo): + available_remotes = [remote.name for remote in repo.remotes] + if 'origin' in available_remotes: + return 'origin' + elif 'upstream' in available_remotes: + return 'upstream' + elif len(available_remotes) > 0: + return available_remotes[0] + + if not available_remotes: + print(f"[ComfyUI-Manager] No remotes are configured for this repository: {repo.working_dir}") + else: + print(f"[ComfyUI-Manager] Available remotes in '{repo.working_dir}': ") + for remote in available_remotes: + print(f"- {remote}") + + return None + + def switch_to_default_branch(repo): + remote_name = get_remote_name(repo) + try: - default_branch = repo.git.symbolic_ref('refs/remotes/origin/HEAD').replace('refs/remotes/origin/', '') + if remote_name is None: + return False + + default_branch = repo.git.symbolic_ref(f'refs/remotes/{remote_name}/HEAD').replace(f'refs/remotes/{remote_name}/', '') repo.git.checkout(default_branch) + return True except: try: repo.git.checkout(repo.heads.master) except: try: - repo.git.checkout('-b', 'master', 'origin/master') + if remote_name is not None: + repo.git.checkout('-b', 'master', f'{remote_name}/master') except: - print("[ComfyUI Manager] Failed to switch to the default branch") + pass + + print("[ComfyUI Manager] Failed to switch to the default branch") + return False def try_install_script(url, repo_path, install_cmd, instant_execution=False): @@ -1778,7 +1812,11 @@ def git_repo_update_check_with(path, do_fetch=False, do_update=False, no_deps=Fa # Fetch the latest commits from the remote repository repo = git.Repo(path) - remote_name = 'origin' + remote_name = get_remote_name(repo) + + if remote_name is None: + raise ValueError(f"No remotes are configured for this repository: {path}") + remote = repo.remote(name=remote_name) if not do_update and repo.head.is_detached: @@ -1788,7 +1826,8 @@ def git_repo_update_check_with(path, do_fetch=False, do_update=False, no_deps=Fa return True, True # detached branch is treated as updatable if repo.head.is_detached: - switch_to_default_branch(repo) + if not switch_to_default_branch(repo): + raise ValueError(f"Failed to switch detached branch to default branch: {path}") current_branch = repo.active_branch branch_name = current_branch.name @@ -1805,7 +1844,9 @@ def git_repo_update_check_with(path, do_fetch=False, do_update=False, no_deps=Fa repo.git.stash() if f'{remote_name}/{branch_name}' not in repo.refs: - switch_to_default_branch(repo) + if not switch_to_default_branch(repo): + raise ValueError(f"Failed to switch to default branch while updating: {path}") + current_branch = repo.active_branch branch_name = current_branch.name @@ -1964,7 +2005,8 @@ def git_pull(path): repo.git.stash() if repo.head.is_detached: - switch_to_default_branch(repo) + if not switch_to_default_branch(repo): + raise ValueError(f"Failed to switch to default branch while pulling: {path}") current_branch = repo.active_branch remote_name = current_branch.tracking_branch().remote_name @@ -2228,14 +2270,15 @@ def update_path(repo_path, instant_execution=False, no_deps=False): repo = git.Repo(repo_path) if repo.head.is_detached: - switch_to_default_branch(repo) + if not switch_to_default_branch(repo): + return "fail" current_branch = repo.active_branch branch_name = current_branch.name if current_branch.tracking_branch() is None: print(f"[ComfyUI-Manager] There is no tracking branch ({current_branch})") - remote_name = 'origin' + remote_name = get_remote_name(repo) else: remote_name = current_branch.tracking_branch().remote_name remote = repo.remote(name=remote_name) @@ -2254,6 +2297,7 @@ def update_path(repo_path, instant_execution=False, no_deps=False): f"-----------------------------------------------------------------------------------------\n" f'git config --global --add safe.directory "{safedir_path}"\n' f"-----------------------------------------------------------------------------------------\n") + return "fail" commit_hash = repo.head.commit.hexsha remote_commit_hash = repo.refs[f'{remote_name}/{branch_name}'].object.hexsha @@ -2323,11 +2367,14 @@ def check_state_of_git_node_pack_single(item, do_fetch=False, do_update_check=Tr if dir_path and os.path.exists(dir_path): if do_update_check: - update_state, success = git_repo_update_check_with(dir_path, do_fetch, do_update) - if (do_update_check or do_update) and update_state: - item['update-state'] = 'true' - elif do_update and not success: - item['update-state'] = 'fail' + try: + update_state, success = git_repo_update_check_with(dir_path, do_fetch, do_update) + if (do_update_check or do_update) and update_state: + item['update-state'] = 'true' + elif do_update and not success: + item['update-state'] = 'fail' + except Exception: + print(f"[ComfyUI-Manager] Failed to check state of the git node pack: {dir_path}") def get_installed_pip_packages(): diff --git a/glob/manager_server.py b/glob/manager_server.py index 94ec3dab..c8ae8787 100644 --- a/glob/manager_server.py +++ b/glob/manager_server.py @@ -912,10 +912,10 @@ async def fix_custom_node(request): res = core.unified_manager.unified_fix(node_name, node_ver) if res.result: - logging.info("After restarting ComfyUI, please refresh the browser.") + logging.info("\nAfter restarting ComfyUI, please refresh the browser.") return web.json_response({}, content_type='application/json') - logging.error(f"ERROR: An error occurred while fixing '{node_name}@{node_ver}'.") + logging.error(f"\nERROR: An error occurred while fixing '{node_name}@{node_ver}'.") return web.Response(status=400, text=f"An error occurred while fixing '{node_name}@{node_ver}'.") @@ -929,10 +929,10 @@ async def install_custom_node_git_url(request): res = await core.gitclone_install(url) if res.action == 'skip': - logging.info(f"Already installed: '{res.target}'") + logging.info(f"\nAlready installed: '{res.target}'") return web.Response(status=200) elif res.result: - logging.info("After restarting ComfyUI, please refresh the browser.") + logging.info("\nAfter restarting ComfyUI, please refresh the browser.") return web.Response(status=200) logging.error(res.msg) @@ -971,10 +971,10 @@ async def uninstall_custom_node(request): res = core.unified_manager.unified_uninstall(node_name, is_unknown) if res.result: - logging.info("After restarting ComfyUI, please refresh the browser.") + logging.info("\nAfter restarting ComfyUI, please refresh the browser.") return web.json_response({}, content_type='application/json') - logging.error(f"ERROR: An error occurred while uninstalling '{node_name}'.") + logging.error(f"\nERROR: An error occurred while uninstalling '{node_name}'.") return web.Response(status=400, text=f"An error occurred while uninstalling '{node_name}'.") @@ -998,10 +998,10 @@ async def update_custom_node(request): manager_util.clear_pip_cache() if res.result: - logging.info("After restarting ComfyUI, please refresh the browser.") + logging.info("\nAfter restarting ComfyUI, please refresh the browser.") return web.json_response({}, content_type='application/json') - logging.error(f"ERROR: An error occurred while updating '{node_name}'.") + logging.error(f"\nERROR: An error occurred while updating '{node_name}'.") return web.Response(status=400, text=f"An error occurred while updating '{node_name}'.") diff --git a/pyproject.toml b/pyproject.toml index 4c8fefe3..c075e02c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-manager" description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI." -version = "3.5.1" +version = "3.6" license = { file = "LICENSE.txt" } dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions"]