Skip to content

96 instead of an exact search implement a fuzzy search to find branch names associated with an issue#97

Open
abuzarmahmood wants to merge 5 commits intomainfrom
96-instead-of-an-exact-search-implement-a-fuzzy-search-to-find-branch-names-associated-with-an-issue
Open

96 instead of an exact search implement a fuzzy search to find branch names associated with an issue#97
abuzarmahmood wants to merge 5 commits intomainfrom
96-instead-of-an-exact-search-implement-a-fuzzy-search-to-find-branch-names-associated-with-an-issue

Conversation

@abuzarmahmood
Copy link
Owner

  • feat: Implement fuzzy branch matching using fuzz.partial_ratio for improved issue-branch association
  • fix: Add missing fuzzywuzzy import in git_utils.py

@abuzarmahmood
Copy link
Owner Author

Generated edit command:

Summary of User's Issues and Requests

The issue involves implementing a fuzzy search mechanism to find branch names associated with an issue. The current exact matching approach is problematic when branch names are truncated or slightly different from the issue title. The last comment suggests focusing on addressing the use of fuzz.partial_ratio instead of fuzz.ratio for better matching.

Overview of Plan to Address the Issues

  1. Identify relevant files that handle branch management and Git operations.
  2. Implement fuzzy search using fuzz.partial_ratio in the identified files.
  3. Ensure the response agent can handle the results from the fuzzy search.

Specific Details of Changes to be Made

  1. Implement Fuzzy Search in Branch Handler

    • File: branch_handler.py
    • Lines: 46-59
    • Description of Change: Modify the logic to use fuzz.partial_ratio for fuzzy matching of branch names.
    • Code Snippet of Edits:
      from fuzzywuzzy import fuzz
      
      # Check local branches
      for branch in repo.heads:
          similarity = fuzz.partial_ratio(possible_branch_name, branch.name)
          if similarity > 80:  # Threshold for fuzzy matching
              related_branches.append((branch.name, False))
      
      # Check remote branches
      for remote in repo.remotes:
          for ref in remote.refs:
              if ref.name.endswith('/HEAD'):
                  continue
              branch_name = ref.name.split('/', 1)[1]
              similarity = fuzz.partial_ratio(possible_branch_name, branch_name)
              if similarity > 80:
                  related_branches.append((branch_name, True))
  2. Update Git Utilities to Support Fuzzy Search

    • File: git_utils.py
    • Lines: 186-209
    • Description of Change: Ensure that the get_issue_related_branches function uses fuzz.partial_ratio for fuzzy matching.
    • Code Snippet of Edits:
      from fuzzywuzzy import fuzz
      
      # Existing logic to get related branches
      related_branches = get_issue_related_branches(repo_path, issue)
      
      # Use fuzzy matching to filter branches
      unique_branches = set([branch_name for branch_name, _ in related_branches])
      branch_dict = {}
      for branch_name in unique_branches:
          similarity = fuzz.partial_ratio(issue.title, branch_name)
          if similarity > 80:
              branch_dict[branch_name] = [related_branches[ind][1] for ind, (name, _) in enumerate(related_branches) if name == branch_name]
  3. Ensure Response Agent Handles Fuzzy Search Results

    • File: response_agent.py
    • Description of Change: Review and adjust the logic to handle multiple branch names returned from the fuzzy search, selecting the most appropriate one based on additional criteria if necessary.

These changes will improve the system's ability to find branches related to an issue by focusing on the best matching substring, even if the branch names are not exact matches to the issue title.

TERMINATE


This response was automatically generated by blech_bot using model gpt-4o

Aider output:

View Aider Output
The --sonnet flag is deprecated and will be removed in a future version. Please use --model sonnet
instead.
Aider v0.76.1
Main model: anthropic/claude-3-7-sonnet-20250219 with diff edit format, infinite output
Weak model: anthropic/claude-3-5-haiku-20241022
Git repo: .git with 11 files
Repo-map: using 4096 tokens, auto refresh


src/branch_handler.py

src/git_utils.py

src/response_agent.py
I'll implement the fuzzy search mechanism to improve branch name matching for issues. The changes 
will focus on using fuzz.partial_ratio instead of exact matching.                                 

First, let's add the necessary imports and modify the branch handler to use fuzzy matching:       

src/branch_handler.py                                                                             

                                                                                                  
 <<<<<<< SEARCH                                                                                   
 """                                                                                              
 Utility functions for handling git branches related to issues                                    
 """                                                                                              
 import os                                                                                        
 import git                                                                                       
 from github.Issue import Issue                                                                   
 from typing import List, Optional, Tuple                                                         
                                                                                                  
 =======                                                                                          
 """                                                                                              
 Utility functions for handling git branches related to issues                                    
 """                                                                                              
 import os                                                                                        
 import git                                                                                       
 from github.Issue import Issue                                                                   
 from typing import List, Optional, Tuple                                                         
 from fuzzywuzzy import fuzz                                                                      
                                                                                                  
 >>>>>>> REPLACE                                                                                  
                                                                                                  

Now let's update the branch matching logic in get_issue_related_branches:                         

src/branch_handler.py                                                                             

                                                                                                  
 <<<<<<< SEARCH                                                                                   
     if len(related_branches) == 0:                                                               
                                                                                                  
         repo = git.Repo(repo_path)                                                               
         possible_branch_name = f"{issue.number}-{'-'.join(issue.title.lower().split(' '))}"      
                                                                                                  
         # Check local branches                                                                   
         for branch in repo.heads:                                                                
             if possible_branch_name in branch.name:                                              
                 related_branches.append((branch.name, False))                                    
                                                                                                  
         # Check remote branches                                                                  
         for remote in repo.remotes:                                                              
             for ref in remote.refs:                                                              
                 # Skip HEAD ref                                                                  
                 if ref.name.endswith('/HEAD'):                                                   
                     continue                                                                     
                 # Remove remote name prefix for comparison                                       
                 branch_name = ref.name.split('/', 1)[1]                                          
                 if possible_branch_name in branch_name:                                          
                     related_branches.append((branch_name, True))                                 
 =======                                                                                          
     if len(related_branches) == 0:                                                               
                                                                                                  
         repo = git.Repo(repo_path)                                                               
         possible_branch_name = f"{issue.number}-{'-'.join(issue.title.lower().split(' '))}"      
         fuzzy_threshold = 80  # Threshold for fuzzy matching (80% similarity)                    
                                                                                                  
         # Check local branches                                                                   
         for branch in repo.heads:                                                                
             # Use partial_ratio for fuzzy matching to find similar branch names                  
             similarity = fuzz.partial_ratio(possible_branch_name, branch.name)                   
             if similarity > fuzzy_threshold:                                                     
                 related_branches.append((branch.name, False))                                    
                                                                                                  
         # Check remote branches                                                                  
         for remote in repo.remotes:                                                              
             for ref in remote.refs:                                                              
                 # Skip HEAD ref                                                                  
                 if ref.name.endswith('/HEAD'):                                                   
                     continue                                                                     
                 # Remove remote name prefix for comparison                                       
                 branch_name = ref.name.split('/', 1)[1]                                          
                 # Use partial_ratio for fuzzy matching                                           
                 similarity = fuzz.partial_ratio(possible_branch_name, branch_name)               
                 if similarity > fuzzy_threshold:                                                 
                     related_branches.append((branch_name, True))                                 
 >>>>>>> REPLACE                                                                                  
                                                                                                  

Now let's update the get_development_branch function in git_utils.py to better handle the results 
from fuzzy matching:                                                                              

src/git_utils.py                                                                                  

                                                                                                  
 <<<<<<< SEARCH                                                                                   
     # Check for existing branches related to this issue                                          
     related_branches = get_issue_related_branches(repo_path, issue)                              
                                                                                                  
     unique_branches = set([branch_name for branch_name, _ in related_branches])                  
     branch_dict = {}                                                                             
     for branch_name in unique_branches:                                                          
         branch_dict[branch_name] = []                                                            
         wanted_inds = [i for i, (name, _) in enumerate(                                          
             related_branches) if name == branch_name]                                            
         for ind in wanted_inds:                                                                  
             branch_dict[branch_name].append(related_branches[ind][1])                            
 =======                                                                                          
     # Check for existing branches related to this issue                                          
     related_branches = get_issue_related_branches(repo_path, issue)                              
                                                                                                  
     # Process branches with fuzzy matching scores                                                
     unique_branches = set([branch_name for branch_name, _ in related_branches])                  
     branch_dict = {}                                                                             
                                                                                                  
     # Create a dictionary of branch names with their remote status                               
     for branch_name in unique_branches:                                                          
         branch_dict[branch_name] = []                                                            
         wanted_inds = [i for i, (name, _) in enumerate(                                          
             related_branches) if name == branch_name]                                            
         for ind in wanted_inds:                                                                  
             branch_dict[branch_name].append(related_branches[ind][1])                            
 >>>>>>> REPLACE                                                                                  
                                                                                                  

Let's also update the response agent to handle the fuzzy search results better:                   

src/response_agent.py                                                                             

                                                                                                  
 <<<<<<< SEARCH                                                                                   
 import subprocess                                                                                
 import os                                                                                        
 from pprint import pprint                                                                        
 from collections.abc import Callable                                                             
 import random                                                                                    
 import traceback                                                                                 
 import json                                                                                      
 import re                                                                                        
 from urlextract import URLExtract                                                                
 =======                                                                                          
 import subprocess                                                                                
 import os                                                                                        
 from pprint import pprint                                                                        
 from collections.abc import Callable                                                             
 import random                                                                                    
 import traceback                                                                                 
 import json                                                                                      
 import re                                                                                        
 from urlextract import URLExtract                                                                
 from fuzzywuzzy import fuzz                                                                      
 >>>>>>> REPLACE                                                                                  
                                                                                                  

Now let's add a helper function to select the best branch when multiple branches are found:       

src/git_utils.py                                                                                  

                                                                                                  
 <<<<<<< SEARCH                                                                                   
 def get_development_branch(issue: Issue, repo_path: str, create: bool = False) -> str:           
 =======                                                                                          
 def select_best_branch(issue: Issue, branches: list) -> str:                                     
     """                                                                                          
     Select the best branch from multiple candidates using fuzzy matching                         
                                                                                                  
     Args:                                                                                        
         issue: The GitHub issue to match against                                                 
         branches: List of branch names to choose from                                            
                                                                                                  
     Returns:                                                                                     
         The best matching branch name                                                            
     """                                                                                          
     issue_title = issue.title.lower()                                                            
     issue_number = str(issue.number)                                                             
                                                                                                  
     # First try to find branches that contain the issue number                                   
     number_branches = [b for b in branches if issue_number in b]                                 
                                                                                                  
     if number_branches:                                                                          
         # If we have branches with the issue number, use fuzzy matching on those                 
         best_branch = max(number_branches,                                                       
                           key=lambda b: fuzz.partial_ratio(issue_title, b))                      
         return best_branch                                                                       
                                                                                                  
     # If no branches with issue number, use fuzzy matching on all branches                       
     best_branch = max(branches,                                                                  
                       key=lambda b: fuzz.partial_ratio(issue_title, b))                          
     return best_branch                                                                           
                                                                                                  
 def get_development_branch(issue: Issue, repo_path: str, create: bool = False) -> str:           
 >>>>>>> REPLACE                                                                                  
                                                                                                  

Finally, let's update the branch selection logic when multiple branches are found:                

src/git_utils.py                                                                                  

                                                                                                  
 <<<<<<< SEARCH                                                                                   
     if len(branch_dict) > 1:                                                                     
         branch_list = "\n".join(                                                                 
             [f"- {branch_name} : Remote = {is_remote}"                                           
              for branch_name, is_remote in branch_dict.items()]                                  
         )                                                                                        
         error_msg = f"Found multiple branches for issue #{issue.number}:\n{branch_list}\n" +\    
             "Please delete or use existing branches before creating a new one."                  
         if "Found multiple branches" not in comments[-1].body:                                   
             write_issue_response(issue, error_msg)                                               
         raise RuntimeError(error_msg)                                                            
 =======                                                                                          
     if len(branch_dict) > 1:                                                                     
         # Try to select the best branch using fuzzy matching                                     
         try:                                                                                     
             best_branch = select_best_branch(issue, list(branch_dict.keys()))                    
             print(f"Selected best matching branch: {best_branch}")                               
             return best_branch                                                                   
         except Exception as e:                                                                   
             # If selection fails, fall back to the error message                                 
             branch_list = "\n".join(                                                             
                 [f"- {branch_name} : Remote = {is_remote}"                                       
                  for branch_name, is_remote in branch_dict.items()]                              
             )                                                                                    
             error_msg = f"Found multiple branches for issue #{issue.number}:\n{branch_list}\n" + 
                 "Please delete or use existing branches before creating a new one."              
             if "Found multiple branches" not in comments[-1].body:                               
                 write_issue_response(issue, error_msg)                                           
             raise RuntimeError(error_msg)                                                        
 >>>>>>> REPLACE                                                                                  
                                                                                                  

These changes implement fuzzy matching using fuzz.partial_ratio to find branches related to       
issues, even when the branch names don't exactly match the issue title. The system will now be    
able to:                                                                                          

 1 Find branches with similar names using fuzzy matching                                          
 2 Select the best matching branch when multiple candidates are found                             
 3 Prioritize branches that contain the issue number                                              

Let's install the required dependency:                                                            

                                                                                                  
 pip install fuzzywuzzy python-Levenshtein                                                        
                                                                                                  

Tokens: 13k sent, 1.7k received. Cost: $0.06 message, $0.06 session.
Applied edit to src/git_utils.py
Applied edit to src/response_agent.py
Applied edit to src/branch_handler.py
Commit 44ec045 feat: Implement fuzzy branch matching using fuzz.partial_ratio for improved 
issue-branch association

# Fix any errors below, if possible.

## Running: /home/exouser/.local/share/uv/tools/aider-chat/bin/python -m flake8 
--select=E9,F821,F823,F831,F406,F407,F701,F702,F704,F706 --show-source --isolated src/git_utils.py

src/git_utils.py:190:41: F821 undefined name 'fuzz'
                          key=lambda b: fuzz.partial_ratio(issue_title, b))
                                        ^
src/git_utils.py:195:37: F821 undefined name 'fuzz'
                      key=lambda b: fuzz.partial_ratio(issue_title, b))
                                    ^

## See relevant lines below marked with █.

src/git_utils.py:
...⋮...
 170│def select_best_branch(issue: Issue, branches: list) -> str:
 171│    """
 172│    Select the best branch from multiple candidates using fuzzy matching
 173│    
 174│    Args:
 175│        issue: The GitHub issue to match against
 176│        branches: List of branch names to choose from
 177│        
 178│    Returns:
 179│        The best matching branch name
...⋮...
 187│    if number_branches:
 188│        # If we have branches with the issue number, use fuzzy matching on those
 189│        best_branch = max(number_branches, 
 190█                          key=lambda b: fuzz.partial_ratio(issue_title, b))
 191│        return best_branch
 192│    
 193│    # If no branches with issue number, use fuzzy matching on all branches
 194│    best_branch = max(branches, 
 195█                      key=lambda b: fuzz.partial_ratio(issue_title, b))
 196│    return best_branch
 197│
 198│def get_development_branch(issue: Issue, repo_path: str, create: bool = False) -> str:
...⋮...


I'll fix the undefined fuzz error in the git_utils.py file by adding the missing import.          

src/git_utils.py                                                                                  

                                                                                                  
 <<<<<<< SEARCH                                                                                   
 """                                                                                              
 Utility functions for interacting with GitHub API                                                
 """                                                                                              
 from typing import List, Dict, Optional, Tuple                                                   
 import os                                                                                        
 import subprocess                                                                                
 import git                                                                                       
 =======                                                                                          
 """                                                                                              
 Utility functions for interacting with GitHub API                                                
 """                                                                                              
 from typing import List, Dict, Optional, Tuple                                                   
 import os                                                                                        
 import subprocess                                                                                
 import git                                                                                       
 from fuzzywuzzy import fuzz                                                                      
 >>>>>>> REPLACE                                                                                  
                                                                                                  

This change adds the missing import for fuzz from the fuzzywuzzy package, which is needed for the 
fuzzy matching functions in select_best_branch.                                                   

Tokens: 15k sent, 143 received. Cost: $0.05 message, $0.11 session.
Applied edit to src/git_utils.py
Commit 4e67941 fix: Add missing fuzzywuzzy import in git_utils.py

pip install fuzzywuzzy python-Levenshtein

This response was automatically generated by blech_bot using model gpt-4o

@abuzarmahmood
Copy link
Owner Author

Instead of fuzzywuzzy, use from thefuzz import fuzz

@abuzarmahmood
Copy link
Owner Author

abuzarmahmood commented Mar 12, 2025

And add name of created branch to the PR creation comment on the issue to avoid this issue for blech_bot created branches

…ranch name comments

This commit message captures the key improvements made across the files:
1. Improved fuzzy search for finding issue-related branches
2. Added branch name to PR creation comments
3. Enhanced branch selection algorithm

The changes implement more robust branch matching and provide better visibility into the branch used for creating pull requests.
@abuzarmahmood
Copy link
Owner Author

Applied changes based on comment:

View Aider Output
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
The --sonnet flag is deprecated and will be removed in a future version. Please use --model sonnet instead.
Aider v0.77.0
Main model: anthropic/claude-3-7-sonnet-20250219 with diff edit format, infinite output
Weak model: anthropic/claude-3-5-haiku-20241022
Git repo: .git with 11 files
Repo-map: using 4096 tokens, auto refresh

Based on your request, I'll identify which files are most likely to need changes to implement:                                     

 1 A fuzzy search for branch names related to issues                                                                               
 2 Adding branch names to PR creation comments                                                                                     

The files that are most likely to need changes are:                                                                                

 1 src/branch_handler.py - For implementing the fuzzy search functionality in the get_issue_related_branches function              
 2 src/git_utils.py - For modifying the PR creation process to include branch names in comments                                    

These are the two files that would need to be edited to implement the requested features.                                          

Tokens: 4.9k sent, 118 received. Cost: $0.02 message, $0.02 session.

src/branch_handler.py

src/git_utils.py
I'll implement the requested changes to enhance the fuzzy search for branch names and add branch name information to PR creation   
comments. Here are the necessary changes:                                                                                          


                                        1. First, let's enhance the branch_handler.py file:                                        

src/branch_handler.py                                                                                                              

                                                                                                                                   
 <<<<<<< SEARCH                                                                                                                    
 def get_issue_related_branches(                                                                                                   
         repo_path: str,                                                                                                           
         issue: Issue                                                                                                              
 ) -> List[Tuple[str, bool]]:                                                                                                      
     """                                                                                                                           
     Uses `gh issue develop -l <issue_number>` to get all branches related to an issue number                                      
                                                                                                                                   
     Args:                                                                                                                         
         repo_path: Path to local git repository                                                                                   
         issue_number: GitHub issue number to search for                                                                           
                                                                                                                                   
     Returns:                                                                                                                      
         List of tuples containing (branch_name, url)                                                                              
     """                                                                                                                           
     issue_number = issue.number                                                                                                   
                                                                                                                                   
     orig_dir = os.getcwd()                                                                                                        
     os.chdir(repo_path)                                                                                                           
                                                                                                                                   
     related_branches = []                                                                                                         
     try:                                                                                                                          
         branches = os.popen(                                                                                                      
             f"gh issue develop -l {issue_number}").read().splitlines()                                                            
         for branch in branches:                                                                                                   
             # Each line is in the format "branch_name url"                                                                        
             branch_name = branch.split('\t')[0]                                                                                   
             url = branch.split('\t')[1]                                                                                           
             related_branches.append((branch_name, url))                                                                           
     except Exception as e:                                                                                                        
         print(f"Error getting related branches: {str(e)}")                                                                        
                                                                                                                                   
     if len(related_branches) == 0:                                                                                                
                                                                                                                                   
         repo = git.Repo(repo_path)                                                                                                
         possible_branch_name = f"{issue.number}-{'-'.join(issue.title.lower().split(' '))}"                                       
         fuzzy_threshold = 80  # Threshold for fuzzy matching (80% similarity)                                                     
                                                                                                                                   
         # Check local branches                                                                                                    
         for branch in repo.heads:                                                                                                 
             # Use partial_ratio for fuzzy matching to find similar branch names                                                   
             similarity = fuzz.partial_ratio(possible_branch_name, branch.name)                                                    
             if similarity > fuzzy_threshold:                                                                                      
                 related_branches.append((branch.name, False))                                                                     
                                                                                                                                   
         # Check remote branches                                                                                                   
         for remote in repo.remotes:                                                                                               
             for ref in remote.refs:                                                                                               
                 # Skip HEAD ref                                                                                                   
                 if ref.name.endswith('/HEAD'):                                                                                    
                     continue                                                                                                      
                 # Remove remote name prefix for comparison                                                                        
                 branch_name = ref.name.split('/', 1)[1]                                                                           
                 # Use partial_ratio for fuzzy matching                                                                            
                 similarity = fuzz.partial_ratio(                                                                                  
                     possible_branch_name, branch_name)                                                                            
                 if similarity > fuzzy_threshold:                                                                                  
                     related_branches.append((branch_name, True))                                                                  
 =======                                                                                                                           
 def get_issue_related_branches(                                                                                                   
         repo_path: str,                                                                                                           
         issue: Issue                                                                                                              
 ) -> List[Tuple[str, bool]]:                                                                                                      
     """                                                                                                                           
     Uses `gh issue develop -l <issue_number>` to get all branches related to an issue number                                      
     and falls back to fuzzy matching if no branches are found through GitHub CLI                                                  
                                                                                                                                   
     Args:                                                                                                                         
         repo_path: Path to local git repository                                                                                   
         issue: GitHub issue to search for                                                                                         
                                                                                                                                   
     Returns:                                                                                                                      
         List of tuples containing (branch_name, is_remote)                                                                        
     """                                                                                                                           
     issue_number = issue.number                                                                                                   
                                                                                                                                   
     orig_dir = os.getcwd()                                                                                                        
     os.chdir(repo_path)                                                                                                           
                                                                                                                                   
     related_branches = []                                                                                                         
     try:                                                                                                                          
         branches = os.popen(                                                                                                      
             f"gh issue develop -l {issue_number}").read().splitlines()                                                            
         for branch in branches:                                                                                                   
             # Each line is in the format "branch_name url"                                                                        
             branch_name = branch.split('\t')[0]                                                                                   
             url = branch.split('\t')[1]                                                                                           
             related_branches.append((branch_name, url))                                                                           
     except Exception as e:                                                                                                        
         print(f"Error getting related branches: {str(e)}")                                                                        
                                                                                                                                   
     if len(related_branches) == 0:                                                                                                
         # Fall back to fuzzy matching if no branches found through GitHub CLI                                                     
         repo = git.Repo(repo_path)                                                                                                
                                                                                                                                   
         # Create a possible branch name based on issue number and title                                                           
         possible_branch_name = f"{issue.number}-{'-'.join(issue.title.lower().split(' '))}"                                       
                                                                                                                                   
         # Also check for just the issue number in branch names                                                                    
         issue_number_str = str(issue.number)                                                                                      
                                                                                                                                   
         # Set threshold for fuzzy matching (80% similarity)                                                                       
         fuzzy_threshold = 80                                                                                                      
                                                                                                                                   
         # Check local branches                                                                                                    
         for branch in repo.heads:                                                                                                 
             # First check if branch contains the issue number                                                                     
             if issue_number_str in branch.name:                                                                                   
                 related_branches.append((branch.name, False))                                                                     
                 continue                                                                                                          
                                                                                                                                   
             # Use partial_ratio for fuzzy matching to find similar branch names                                                   
             similarity = fuzz.partial_ratio(possible_branch_name, branch.name)                                                    
             if similarity > fuzzy_threshold:                                                                                      
                 related_branches.append((branch.name, False))                                                                     
                                                                                                                                   
         # Check remote branches                                                                                                   
         for remote in repo.remotes:                                                                                               
             for ref in remote.refs:                                                                                               
                 # Skip HEAD ref                                                                                                   
                 if ref.name.endswith('/HEAD'):                                                                                    
                     continue                                                                                                      
                 # Remove remote name prefix for comparison                                                                        
                 branch_name = ref.name.split('/', 1)[1]                                                                           
                                                                                                                                   
                 # First check if branch contains the issue number                                                                 
                 if issue_number_str in branch_name:                                                                               
                     related_branches.append((branch_name, True))                                                                  
                     continue                                                                                                      
                                                                                                                                   
                 # Use partial_ratio for fuzzy matching                                                                            
                 similarity = fuzz.partial_ratio(                                                                                  
                     possible_branch_name, branch_name)                                                                            
                 if similarity > fuzzy_threshold:                                                                                  
                     related_branches.append((branch_name, True))                                                                  
 >>>>>>> REPLACE                                                                                                                   
                                                                                                                                   


                    2. Now, let's modify the git_utils.py file to include branch name in PR creation comments:                     

src/git_utils.py                                                                                                                   

                                                                                                                                   
 <<<<<<< SEARCH                                                                                                                    
 def create_pull_request(repo_path: str) -> str:                                                                                   
     """                                                                                                                           
     Creates a pull request from the current branch                                                                                
                                                                                                                                   
     Args:                                                                                                                         
         repo_path: Path to local git repository                                                                                   
                                                                                                                                   
     Returns:                                                                                                                      
         URL of the created pull request                                                                                           
                                                                                                                                   
     Raises:                                                                                                                       
         subprocess.CalledProcessError: If gh commands fail                                                                        
         ValueError: If gh CLI is not installed                                                                                    
     """                                                                                                                           
     try:                                                                                                                          
         # Change to repo directory                                                                                                
         original_dir = os.getcwd()                                                                                                
         os.chdir(repo_path)                                                                                                       
                                                                                                                                   
         # Create pull request                                                                                                     
         result = subprocess.run(['gh', 'pr', 'create', '--fill'],                                                                 
                                 check=True,                                                                                       
                                 capture_output=True,                                                                              
                                 text=True)                                                                                        
                                                                                                                                   
         # Return to original directory                                                                                            
         os.chdir(original_dir)                                                                                                    
                                                                                                                                   
         # Return the PR URL from the output                                                                                       
         return result.stdout.strip()                                                                                              
 =======                                                                                                                           
 def create_pull_request(repo_path: str) -> str:                                                                                   
     """                                                                                                                           
     Creates a pull request from the current branch                                                                                
                                                                                                                                   
     Args:                                                                                                                         
         repo_path: Path to local git repository                                                                                   
                                                                                                                                   
     Returns:                                                                                                                      
         URL of the created pull request                                                                                           
                                                                                                                                   
     Raises:                                                                                                                       
         subprocess.CalledProcessError: If gh commands fail                                                                        
         ValueError: If gh CLI is not installed                                                                                    
     """                                                                                                                           
     try:                                                                                                                          
         # Change to repo directory                                                                                                
         original_dir = os.getcwd()                                                                                                
         os.chdir(repo_path)                                                                                                       
                                                                                                                                   
         # Get current branch name                                                                                                 
         current_branch = get_current_branch(repo_path)                                                                            
                                                                                                                                   
         # Create pull request                                                                                                     
         result = subprocess.run(['gh', 'pr', 'create', '--fill'],                                                                 
                                 check=True,                                                                                       
                                 capture_output=True,                                                                              
                                 text=True)                                                                                        
                                                                                                                                   
         # Return to original directory                                                                                            
         os.chdir(original_dir)                                                                                                    
                                                                                                                                   
         # Return the PR URL from the output with branch information                                                               
         pr_url = result.stdout.strip()                                                                                            
         return pr_url, current_branch                                                                                             
 >>>>>>> REPLACE                                                                                                                   
                                                                                                                                   

src/git_utils.py                                                                                                                   

                                                                                                                                   
 <<<<<<< SEARCH                                                                                                                    
 def create_pull_request_from_issue(issue: Issue, repo_path: str) -> str:                                                          
     """                                                                                                                           
     Creates a pull request from an issue using GitHub CLI                                                                         
                                                                                                                                   
     Args:                                                                                                                         
         issue: The GitHub issue to create a PR from                                                                               
         repo_path: Path to local git repository                                                                                   
                                                                                                                                   
     Returns:                                                                                                                      
         URL of the created pull request                                                                                           
     """                                                                                                                           
     branch = get_development_branch(issue, repo_path)                                                                             
     return create_pull_request(repo_path)                                                                                         
 =======                                                                                                                           
 def create_pull_request_from_issue(issue: Issue, repo_path: str) -> str:                                                          
     """                                                                                                                           
     Creates a pull request from an issue using GitHub CLI                                                                         
                                                                                                                                   
     Args:                                                                                                                         
         issue: The GitHub issue to create a PR from                                                                               
         repo_path: Path to local git repository                                                                                   
                                                                                                                                   
     Returns:                                                                                                                      
         URL of the created pull request                                                                                           
     """                                                                                                                           
     branch = get_development_branch(issue, repo_path)                                                                             
     pr_url, branch_name = create_pull_request(repo_path)                                                                          
                                                                                                                                   
     # Add a comment to the issue with the branch name used for the PR                                                             
     comment_text = f"Created pull request from branch: `{branch_name}`\n{pr_url}"                                                 
     write_issue_response(issue, comment_text)                                                                                     
                                                                                                                                   
     return pr_url                                                                                                                 
 >>>>>>> REPLACE                                                                                                                   
                                                                                                                                   


                         3. Let's also update the select_best_branch function to improve branch selection:                         

src/git_utils.py                                                                                                                   

                                                                                                                                   
 <<<<<<< SEARCH                                                                                                                    
 def select_best_branch(issue: Issue, branches: list) -> str:                                                                      
     """                                                                                                                           
     Select the best branch from multiple candidates using fuzzy matching                                                          
                                                                                                                                   
     Args:                                                                                                                         
         issue: The GitHub issue to match against                                                                                  
         branches: List of branch names to choose from                                                                             
                                                                                                                                   
     Returns:                                                                                                                      
         The best matching branch name                                                                                             
     """                                                                                                                           
     issue_title = issue.title.lower()                                                                                             
     issue_number = str(issue.number)                                                                                              
                                                                                                                                   
     # First try to find branches that contain the issue number                                                                    
     number_branches = [b for b in branches if issue_number in b]                                                                  
                                                                                                                                   
     if number_branches:                                                                                                           
         # If we have branches with the issue number, use fuzzy matching on those                                                  
         best_branch = max(number_branches,                                                                                        
                           key=lambda b: fuzz.partial_ratio(issue_title, b))                                                       
         return best_branch                                                                                                        
                                                                                                                                   
     # If no branches with issue number, use fuzzy matching on all branches                                                        
     best_branch = max(branches,                                                                                                   
                       key=lambda b: fuzz.partial_ratio(issue_title, b))                                                           
     return best_branch                                                                                                            
 =======                                                                                                                           
 def select_best_branch(issue: Issue, branches: list) -> str:                                                                      
     """                                                                                                                           
     Select the best branch from multiple candidates using fuzzy matching                                                          
                                                                                                                                   
     Args:                                                                                                                         
         issue: The GitHub issue to match against                                                                                  
         branches: List of branch names to choose from                                                                             
                                                                                                                                   
     Returns:                                                                                                                      
         The best matching branch name                                                                                             
     """                                                                                                                           
     issue_title = issue.title.lower()                                                                                             
     issue_number = str(issue.number)                                                                                              
                                                                                                                                   
     # Generate a normalized branch name from the issue                                                                            
     normalized_branch = f"{issue_number}-{'-'.join(issue_title.split())}"                                                         
                                                                                                                                   
     # First try to find branches that contain the issue number                                                                    
     number_branches = [b for b in branches if issue_number in b]                                                                  
                                                                                                                                   
     if number_branches:                                                                                                           
         if len(number_branches) == 1:                                                                                             
             # If only one branch with the issue number, return it                                                                 
             return number_branches[0]                                                                                             
                                                                                                                                   
         # If multiple branches with issue number, use fuzzy matching on those                                                     
         # Use token_sort_ratio for better matching with word order differences                                                    
         best_branch = max(number_branches,                                                                                        
                           key=lambda b: fuzz.token_sort_ratio(normalized_branch, b))                                              
         return best_branch                                                                                                        
                                                                                                                                   
     # If no branches with issue number, use fuzzy matching on all branches                                                        
     # Use token_sort_ratio for better matching with word order differences                                                        
     best_branch = max(branches,                                                                                                   
                       key=lambda b: fuzz.token_sort_ratio(normalized_branch, b))                                                  
     return best_branch                                                                                                            
 >>>>>>> REPLACE                                                                                                                   
                                                                                                                                   

These changes will:                                                                                                                

 1 Enhance the fuzzy search in get_issue_related_branches to first check for branches containing the issue number directly, then   
   fall back to fuzzy matching.                                                                                                    
 2 Modify create_pull_request to return both the PR URL and the branch name.                                                       
 3 Update create_pull_request_from_issue to include the branch name in the comment on the issue.                                   
 4 Improve the select_best_branch function to use better fuzzy matching algorithms and handle the case of a single matching branch 
   more efficiently.                                                                                                               

You may need to install the fuzzywuzzy package if it's not already installed:                                                      

                                                                                                                                   
 pip install fuzzywuzzy python-Levenshtein                                                                                         
                                                                                                                                   

Tokens: 8.9k sent, 2.4k received. Cost: $0.06 message, $0.08 session.
Applied edit to src/git_utils.py
Applied edit to src/branch_handler.py
Commit 0030825 feat: Enhance branch search and PR creation with fuzzy matching and branch name comments

This commit message captures the key improvements made across the files:
1. Improved fuzzy search for finding issue-related branches
2. Added branch name to PR creation comments
3. Enhanced branch selection algorithm

The changes implement more robust branch matching and provide better visibility into the branch used for creating pull requests.

pip install fuzzywuzzy python-Levenshtein


This response was automatically generated by blech_bot using model gpt-4o

@abuzarmahmood
Copy link
Owner Author

Skipped PR #97: PR #97 does not have blech_bot label


This response was automatically generated by blech_bot using model gpt-4o

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Instead of an exact search, implement a fuzzy search to find branch names associated with an issue

1 participant