Source code for scitex_git._branch

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/git/branch.py

"""
Git branch operations.

Examples
--------
>>> from pathlib import Path
>>> from scitex.git import git_branch_rename, git_checkout_new_branch
>>> repo = Path("/path/to/repo")
>>> git_branch_rename(repo, "main")
>>> git_checkout_new_branch(repo, "feature/new-feature")
"""

from pathlib import Path

from logging import getLogger
from ._vendor_sh import sh

from ._constants import EXIT_FAILURE, EXIT_SUCCESS
from ._utils import _in_directory
from ._validation import validate_branch_name, validate_path

logger = getLogger(__name__)


[docs] def git_branch_rename(repo_path: Path, new_name: str, verbose: bool = True) -> bool: """ Rename current branch. Parameters ---------- repo_path : Path Git repository path new_name : str New branch name verbose : bool Enable verbose output Returns ------- bool True if successful, False if: - repo_path is not a git repository - new_name is invalid - git branch command fails Examples -------- >>> git_branch_rename(Path("/my/repo"), "main") True """ valid, error = validate_path(repo_path, must_exist=True) if not valid: logger.error(error) return False if not (repo_path / ".git").exists(): logger.error(f"Not a git repository: {repo_path}") return False valid, error = validate_branch_name(new_name) if not valid: logger.error(error) return False with _in_directory(repo_path): result = sh( ["git", "branch", "-M", new_name], verbose=verbose, return_as="dict" ) if not result["success"]: error_msg = ( result["stderr"].strip() if result["stderr"] else "Unknown error" ) logger.error(f"Failed to rename branch in {repo_path}: {error_msg}") return False if verbose: logger.info(f"Branch renamed to {new_name}") return True
[docs] def git_checkout_new_branch( repo_path: Path, branch_name: str, verbose: bool = True ) -> bool: """ Create and checkout a new branch. Parameters ---------- repo_path : Path Git repository path branch_name : str New branch name verbose : bool Enable verbose output Returns ------- bool True if successful, False if: - repo_path is not a git repository - branch_name is invalid - git checkout command fails Examples -------- >>> git_checkout_new_branch(Path("/my/repo"), "feature/auth") True """ valid, error = validate_path(repo_path, must_exist=True) if not valid: logger.error(error) return False if not (repo_path / ".git").exists(): logger.error(f"Not a git repository: {repo_path}") return False valid, error = validate_branch_name(branch_name) if not valid: logger.error(error) return False with _in_directory(repo_path): result = sh( ["git", "checkout", "-b", branch_name], verbose=verbose, return_as="dict" ) if not result["success"]: error_msg = ( result["stderr"].strip() if result["stderr"] else "Unknown error" ) logger.error( f"Failed to create branch {branch_name} in {repo_path}: {error_msg}" ) return False if verbose: logger.info(f"Switched to new branch: {branch_name}") return True
def main(args): if args.action == "rename": success = git_branch_rename(args.repo_path, args.branch_name, args.verbose) elif args.action == "checkout": success = git_checkout_new_branch( args.repo_path, args.branch_name, args.verbose ) else: return EXIT_FAILURE return EXIT_SUCCESS if success else EXIT_FAILURE def parse_args(): """Parse command line arguments.""" import argparse parser = argparse.ArgumentParser() parser.add_argument("--repo-path", type=Path, required=True) parser.add_argument("--action", choices=["rename", "checkout"], required=True) parser.add_argument("--branch-name", required=True) parser.add_argument("--verbose", action="store_true") return parser.parse_args() def run_session(): """Initialize scitex framework, run main function, and cleanup.""" from ._session import run_with_session run_with_session(parse_args, main) __all__ = [ "git_branch_rename", "git_checkout_new_branch", ] if __name__ == "__main__": run_session() # EOF