diff --git a/cm_cli/__main__.py b/cm_cli/__main__.py index b302872c..554a7e03 100644 --- a/cm_cli/__main__.py +++ b/cm_cli/__main__.py @@ -238,18 +238,29 @@ def install_node(node_spec_str, is_all=False, cnt_msg='', **kwargs): def reinstall_node(node_spec_str, is_all=False, cnt_msg=''): - node_spec = unified_manager.resolve_node_spec(node_spec_str) + if core.is_valid_url(node_spec_str): + # URL-based: resolve_node_spec returns the full URL as node_name, + # but internal dicts are keyed by repo basename or cnr_id. + url = node_spec_str.rstrip('/') + cnr = unified_manager.get_cnr_by_repo(url) + if cnr: + node_id = cnr['id'] + unified_manager.unified_uninstall(node_id, False) + unified_manager.purge_node_state(node_id) + else: + repo_name = os.path.splitext(os.path.basename(url))[0] + unified_manager.unified_uninstall(repo_name, True) + unified_manager.purge_node_state(repo_name) - node_name, version_spec, _ = node_spec + install_node(node_spec_str, is_all=is_all, cnt_msg=cnt_msg, raise_on_fail=True) + else: + node_spec = unified_manager.resolve_node_spec(node_spec_str) + node_name, version_spec, _ = node_spec - # Best-effort uninstall via normal path - unified_manager.unified_uninstall(node_name, version_spec == 'unknown') + unified_manager.unified_uninstall(node_name, version_spec == 'unknown') + unified_manager.purge_node_state(node_name) - # Fallback: purge all state and directories regardless of categorization - # Handles categorization mismatch between cm_cli invocations (e.g. unknown→nightly) - unified_manager.purge_node_state(node_name) - - install_node(node_name, is_all=is_all, cnt_msg=cnt_msg, raise_on_fail=True) + install_node(node_name, is_all=is_all, cnt_msg=cnt_msg, raise_on_fail=True) def fix_node(node_spec_str, is_all=False, cnt_msg=''): diff --git a/comfyui_manager/common/git_helper.py b/comfyui_manager/common/git_helper.py index c8ae6cb2..46e7ad88 100644 --- a/comfyui_manager/common/git_helper.py +++ b/comfyui_manager/common/git_helper.py @@ -101,7 +101,11 @@ def gitclone(custom_nodes_path, url, target_hash=None, repo_path=None): repo_path = os.path.join(custom_nodes_path, repo_name) # Clone the repository from the remote URL - repo = git.Repo.clone_from(url, repo_path, recursive=True, progress=GitProgress()) + # Disable tqdm progress when stderr is piped to avoid deadlock on Windows. + # When a parent process captures stderr via PIPE, tqdm output can fill the + # 4KB Windows pipe buffer, blocking GitPython's progress reader and git itself. + progress = GitProgress() if sys.stderr.isatty() else None + repo = git.Repo.clone_from(url, repo_path, recursive=True, progress=progress) if target_hash is not None: print(f"CHECKOUT: {repo_name} [{target_hash}]")