Coverage for src\gibr\git.py: 59%

37 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-20 09:51 +0300

1"""Git-related operations.""" 

2 

3import logging 

4 

5import click 

6from git import GitCommandError, Repo 

7 

8from gibr.notify import error, info, success, warning 

9 

10 

11def create_and_push_branch(branch_name: str): 

12 """Create a new branch and push it to origin.""" 

13 try: 

14 repo = Repo(".") 

15 if repo.is_dirty(): 

16 warning("Working tree is dirty — uncommitted changes present.") 

17 

18 # Handle repo with no commits yet (no HEAD) 

19 if not repo.head.is_valid(): 

20 error("Please make an initial commit before using gibr.") 

21 return 

22 

23 # Handle detached HEAD (e.g. checkout of specific commit) 

24 if repo.head.is_detached: 

25 warning("HEAD is detached (not on a branch).") 

26 

27 # Determine current branch 

28 current_branch = repo.active_branch.name 

29 logging.debug(f"Current branch: {current_branch}") 

30 

31 # Check if branch already exists locally 

32 if branch_name in repo.heads: 

33 if current_branch == branch_name: 

34 warning(f"Branch '{branch_name}' already exists and is checked out") 

35 return 

36 else: 

37 warning(f"Branch '{branch_name}' already exists locally.") 

38 # Ask user what to do 

39 if click.confirm( 

40 "Would you like to create a new branch with a suffix?", default=True 

41 ): 

42 suffix = click.prompt( 

43 "Enter suffix", default="take2", show_default=True 

44 ) 

45 new_name = f"{branch_name}-{suffix}" 

46 info(f"Creating new branch '{new_name}' instead.") 

47 return create_and_push_branch(new_name) 

48 else: 

49 info("Operation canceled by user.") 

50 return 

51 else: 

52 # Create new branch from current HEAD 

53 new_branch = repo.create_head(branch_name) 

54 success(f"Created branch '{branch_name}' from {current_branch}.") 

55 

56 # Checkout new branch 

57 new_branch.checkout() 

58 success(f"Checked out branch: {branch_name}") 

59 

60 # Push to origin 

61 origin = repo.remote(name="origin") 

62 origin.push(refspec=f"{branch_name}:{branch_name}", set_upstream=True) 

63 success(f"Pushed branch '{branch_name}' to origin.") 

64 

65 except GitCommandError as e: 

66 error(f"Git command failed: {e}")