branchGit/mobius_repos.py

205 lines
7.2 KiB
Python
Executable File

import os
import subprocess
import argparse
class Colors:
HEADER = '\033[95m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
def print_colored(message, color, bold=False):
"""
Print a colored message to the terminal
"""
if bold:
print(f"{Colors.BOLD}{color}{message}{Colors.ENDC}")
else:
print(f"{color}{message}{Colors.ENDC}")
def create_new_branch(repo_path, branch_name):
"""
Create a new branch from 'develop' branch in the repository
"""
try:
os.chdir(repo_path)
print_colored(f"\n=== Creating new branch in repository: {repo_path} ===", Colors.HEADER, bold=True)
if not os.path.exists('.git'):
print_colored(f"The folder {repo_path} is not a git repository!", Colors.RED)
return False
current_branch = subprocess.check_output(['git', 'branch', '--show-current']).decode().strip()
print_colored(f"Current branch: {current_branch}", Colors.BLUE)
# Check if develop branch exists
branches = subprocess.check_output(['git', 'branch', '-a']).decode()
if 'develop' not in branches and 'origin/develop' not in branches:
print_colored("The 'develop' branch does not exist!", Colors.RED)
return False
# First checkout develop branch
subprocess.run(['git', 'checkout', 'develop'], check=True)
print_colored("Switched to the 'develop' branch", Colors.GREEN)
# Pull latest changes from develop
print_colored("Pulling latest changes from develop...", Colors.BLUE)
subprocess.run(['git', 'pull'], check=True)
# Check if the new branch already exists
if branch_name in branches:
print_colored(f"Branch '{branch_name}' already exists!", Colors.YELLOW)
return False
# Create new branch from develop
subprocess.run(['git', 'checkout', '-b', branch_name], check=True)
print_colored(f"Successfully created and switched to branch: {branch_name}", Colors.GREEN)
try:
subprocess.run(['git', 'push', '-u', 'origin', branch_name], check=True)
print_colored("Successfully pushed new branch to remote", Colors.GREEN)
except subprocess.CalledProcessError:
print_colored("Failed to push branch to remote. Branch created locally only.", Colors.YELLOW)
return True
except subprocess.CalledProcessError as e:
print_colored(f"Error while working with git: {str(e)}", Colors.RED)
return False
except Exception as e:
print_colored(f"An unexpected error occurred: {str(e)}", Colors.RED)
return False
def git_checkout_and_pull(repo_path):
"""
Switch to the 'develop' branch and pull the latest changes for the given repository.
"""
try:
os.chdir(repo_path)
print_colored(f"\n=== Processing repository: {repo_path} ===", Colors.HEADER, bold=True)
if not os.path.exists('.git'):
print_colored(f"The folder {repo_path} is not a git repository!", Colors.RED)
return False
current_branch = subprocess.check_output(['git', 'branch', '--show-current']).decode().strip()
print_colored(f"Current branch: {current_branch}", Colors.BLUE)
branches = subprocess.check_output(['git', 'branch', '-a']).decode()
if 'develop' not in branches and 'origin/develop' not in branches:
print_colored("The 'develop' branch does not exist!", Colors.RED)
return False
subprocess.run(['git', 'checkout', 'develop'], check=True)
print_colored("Switched to the 'develop' branch", Colors.GREEN)
subprocess.run(['git', 'pull'], check=True)
print_colored("Successfully pulled the latest changes", Colors.GREEN)
return True
except subprocess.CalledProcessError as e:
print_colored(f"Error while working with git: {str(e)}", Colors.RED)
return False
except Exception as e:
print_colored(f"An unexpected error occurred: {str(e)}", Colors.RED)
return False
def load_repositories(config_file):
"""
Load repository paths from a configuration file.
"""
try:
with open(config_file, 'r') as file:
repositories = [line.strip() for line in file if line.strip()]
return repositories
except FileNotFoundError:
print_colored(f"Configuration file '{config_file}' not found!", Colors.RED)
return []
except Exception as e:
print_colored(f"An error occurred while reading the configuration file: {str(e)}", Colors.RED)
return []
def main():
# Setup argument parser with detailed help
parser = argparse.ArgumentParser(
prog='mob_repos.py',
description='''
Git repository management script for multiple repositories.
This script helps manage multiple Git repositories defined in repos.txt file.
It can perform bulk operations like switching to develop branch, pulling latest changes,
or creating new branches across all repositories.
''',
epilog='''
Examples:
python3 mob_repos.py # Switch to develop and pull in all repos
python3 mob_repos.py -bc feature/GND1111-testing-repo # Create new branch from develop in all repos
python3 mob_repos.py --help # Show this help message
''',
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
'-bc', '--branch-create',
help='Create a new branch from develop in all repositories (e.g., feature/GND1111-testing-repo)',
metavar='BRANCH_NAME'
)
parser.add_argument(
'-c', '--config',
help='Path to configuration file (default: repos.txt)',
default='repos.txt',
metavar='CONFIG_FILE'
)
args = parser.parse_args()
# Load repository paths
print_colored("Loading repositories from configuration file...", Colors.BLUE)
repositories = load_repositories(args.config)
if not repositories:
print_colored("No repositories found in the configuration file. Exiting.", Colors.RED)
return
print_colored(f"Found {len(repositories)} repositories", Colors.GREEN)
# Save the original working directory
original_dir = os.getcwd()
# Process each repository
success_count = 0
fail_count = 0
for repo in repositories:
if not os.path.exists(repo):
print_colored(f"Repository {repo} does not exist!", Colors.RED)
fail_count += 1
continue
if args.branch_create:
success = create_new_branch(repo, args.branch_create)
else:
success = git_checkout_and_pull(repo)
if success:
success_count += 1
else:
fail_count += 1
os.chdir(original_dir)
# Print summary
print_colored("\n=== Summary ===", Colors.HEADER, bold=True)
print_colored(f"Successfully processed: {success_count} repositories", Colors.GREEN)
if fail_count > 0:
print_colored(f"Failed: {fail_count} repositories", Colors.RED)
print_colored("Script execution completed!", Colors.GREEN)
if __name__ == "__main__":
main()