mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2025-12-17 02:12:58 +08:00
- Use --ff-only flag to detect non-fast-forward situations - Create backup branch before resetting divergent local branch - Reset to remote branch when fast-forward is not possible - Add timestamp_utils.py for Mac datetime module compatibility - Migrate all datetime usages to centralized utilities - Bump version to 4.0.3b5 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
137 lines
3.6 KiB
Python
137 lines
3.6 KiB
Python
"""
|
|
Robust timestamp utilities with datetime fallback.
|
|
|
|
Some environments (especially Mac) have issues with the datetime module
|
|
due to local file name conflicts or Homebrew Python module path issues.
|
|
"""
|
|
|
|
import logging
|
|
import time as time_module
|
|
import uuid
|
|
|
|
_datetime_available = None
|
|
_dt_datetime = None
|
|
|
|
|
|
def _init_datetime():
|
|
"""Initialize datetime availability check (lazy, once)."""
|
|
global _datetime_available, _dt_datetime
|
|
if _datetime_available is not None:
|
|
return
|
|
|
|
try:
|
|
import datetime as dt
|
|
if hasattr(dt, 'datetime'):
|
|
from datetime import datetime as dt_datetime
|
|
_dt_datetime = dt_datetime
|
|
_datetime_available = True
|
|
return
|
|
except Exception as e:
|
|
logging.debug(f"[ComfyUI-Manager] datetime import failed: {e}")
|
|
|
|
_datetime_available = False
|
|
logging.warning("[ComfyUI-Manager] datetime unavailable, using time module fallback")
|
|
|
|
|
|
def current_timestamp() -> str:
|
|
"""
|
|
Get current timestamp for logging.
|
|
Format: YYYY-MM-DD HH:MM:SS.mmm (or Unix timestamp if fallback)
|
|
"""
|
|
_init_datetime()
|
|
if _datetime_available:
|
|
return _dt_datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
|
|
return str(time_module.time()).split('.')[0]
|
|
|
|
|
|
def get_timestamp_for_filename() -> str:
|
|
"""
|
|
Get timestamp suitable for filenames.
|
|
Format: YYYYMMDD_HHMMSS
|
|
"""
|
|
_init_datetime()
|
|
if _datetime_available:
|
|
return _dt_datetime.now().strftime('%Y%m%d_%H%M%S')
|
|
return time_module.strftime('%Y%m%d_%H%M%S')
|
|
|
|
|
|
def get_timestamp_for_path() -> str:
|
|
"""
|
|
Get timestamp for path/directory names.
|
|
Format: YYYY-MM-DD_HH-MM-SS
|
|
"""
|
|
_init_datetime()
|
|
if _datetime_available:
|
|
return _dt_datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
|
|
return time_module.strftime('%Y-%m-%d_%H-%M-%S')
|
|
|
|
|
|
def get_backup_branch_name(repo=None) -> str:
|
|
"""
|
|
Get backup branch name with current timestamp.
|
|
Format: backup_YYYYMMDD_HHMMSS (or backup_YYYYMMDD_HHMMSS_N if exists)
|
|
|
|
Args:
|
|
repo: Optional git.Repo object. If provided, checks for name collisions
|
|
and adds sequential suffix if needed.
|
|
|
|
Returns:
|
|
Unique backup branch name.
|
|
"""
|
|
base_name = f'backup_{get_timestamp_for_filename()}'
|
|
|
|
if repo is None:
|
|
return base_name
|
|
|
|
# Check if branch exists
|
|
try:
|
|
existing_branches = {b.name for b in repo.heads}
|
|
except Exception:
|
|
return base_name
|
|
|
|
if base_name not in existing_branches:
|
|
return base_name
|
|
|
|
# Add sequential suffix
|
|
for i in range(1, 100):
|
|
new_name = f'{base_name}_{i}'
|
|
if new_name not in existing_branches:
|
|
return new_name
|
|
|
|
# Ultimate fallback: use UUID (very unlikely to reach here)
|
|
return f'{base_name}_{uuid.uuid4().hex[:6]}'
|
|
|
|
|
|
def get_now():
|
|
"""
|
|
Get current datetime object.
|
|
Returns datetime.now() if available, otherwise a FakeDatetime object
|
|
that supports basic operations (timestamp(), strftime()).
|
|
"""
|
|
_init_datetime()
|
|
if _datetime_available:
|
|
return _dt_datetime.now()
|
|
|
|
# Fallback: return object with basic datetime-like interface
|
|
t = time_module.localtime()
|
|
|
|
class FakeDatetime:
|
|
def timestamp(self):
|
|
return time_module.time()
|
|
|
|
def strftime(self, fmt):
|
|
return time_module.strftime(fmt, t)
|
|
|
|
def isoformat(self):
|
|
return time_module.strftime('%Y-%m-%dT%H:%M:%S', t)
|
|
|
|
return FakeDatetime()
|
|
|
|
|
|
def get_unix_timestamp() -> float:
|
|
"""Get current Unix timestamp."""
|
|
_init_datetime()
|
|
if _datetime_available:
|
|
return _dt_datetime.now().timestamp()
|
|
return time_module.time()
|