parameters: (clang_format, commit_prior_to_reformat,
                       commit_after_reformat)
docstring: Reformat a branch made before a clang-format run
docstring_summary: Reformat a branch made before a clang-format run
docstring_tokens: Reformat a branch made before a clang - format run
function: def _reformat_branch(clang_format, commit_prior_to_reformat,
                       commit_after_reformat):
      """Reformat a branch made before a clang-format run
      """
      try:
          clang_format = ClangFormat(clang_format)
      except NameError as e:
          print(e)
          return False
  
      if os.getcwd() != get_base_dir():
          raise ValueError("reformat-branch must be run from the repo root")
  
      repo = Repo(get_base_dir())
  
      # Validate that user passes valid commits
      if not repo.is_commit(commit_prior_to_reformat):
          raise ValueError(
              "Commit Prior to Reformat '%s' is not a valid commit in this repo"
              % commit_prior_to_reformat)
  
      if not repo.is_commit(commit_after_reformat):
          raise ValueError(
              "Commit After Reformat '%s' is not a valid commit in this repo" %
              commit_after_reformat)
  
      if not repo.is_ancestor(commit_prior_to_reformat, commit_after_reformat):
          raise ValueError((
              "Commit Prior to Reformat '%s' is not a valid ancestor of Commit After" +
              " Reformat '%s' in this repo") % (commit_prior_to_reformat,
                                                commit_after_reformat))
  
      # Validate the user is on a local branch that has the right merge base
      if repo.is_detached():
          raise ValueError(
              "You must not run this script in a detached HEAD state")
  
      # Validate the user has no pending changes
      if repo.is_working_tree_dirty():
          raise ValueError(
              "Your working tree has pending changes. You must have a clean working tree before proceeding."
          )
  
      merge_base = repo.get_merge_base(commit_prior_to_reformat)
  
      if not merge_base == commit_prior_to_reformat:
          raise ValueError(
              "Please rebase to '%s' and resolve all conflicts before running this script"
              % (commit_prior_to_reformat))
  
      # We assume the target branch is main, it could be a different branch if needed for testing
      merge_base = repo.get_merge_base("main")
  
      if not merge_base == commit_prior_to_reformat:
          raise ValueError(
              "This branch appears to already have advanced too far through the merge process"
          )
  
      # Everything looks good so lets start going through all the commits
      branch_name = repo.get_branch_name()
      new_branch = "%s-reformatted" % branch_name
  
      if repo.does_branch_exist(new_branch):
          raise ValueError(
              "The branch '%s' already exists. Please delete the branch '%s', or rename the current branch."
              % (new_branch, new_branch))
  
      commits = get_list_from_lines(
          repo.log([
              "--reverse", "--pretty=format:%H", "%s..HEAD" %
              commit_prior_to_reformat
          ]))
  
      previous_commit_base = commit_after_reformat
  
      # Go through all the commits the user made on the local branch and migrate to a new branch
      # that is based on post_reformat commits instead
      for commit_hash in commits:
          repo.checkout(["--quiet", commit_hash])
  
          deleted_files = []
  
          # Format each of the files by checking out just a single commit from the user's branch
          commit_files = get_list_from_lines(repo.diff(["HEAD~", "--name-only"]))
  
          for commit_file in commit_files:
  
              # Format each file needed if it was not deleted
              if not os.path.exists(commit_file):
                  print(
                      "Skipping file '%s' since it has been deleted in commit '%s'"
                      % (commit_file, commit_hash))
                  deleted_files.append(commit_file)
                  continue
  
              if files_match.search(commit_file):
                  clang_format.format(commit_file)
              else:
                  print(
                      "Skipping file '%s' since it is not a file clang_format should format"
                      % commit_file)
  
          # Check if anything needed reformatting, and if so amend the commit
          if not repo.is_working_tree_dirty():
              print("Commit %s needed no reformatting" % commit_hash)
          else:
              repo.commit(["--all", "--amend", "--no-edit"])
  
          # Rebase our new commit on top the post-reformat commit
          previous_commit = repo.rev_parse(["HEAD"])
  
          # Checkout the new branch with the reformatted commits
          # Note: we will not name as a branch until we are done with all commits on the local branch
          repo.checkout(["--quiet", previous_commit_base])
  
          # Copy each file from the reformatted commit on top of the post reformat
          diff_files = get_list_from_lines(
              repo.diff([
                  "%s~..%s" % (previous_commit, previous_commit), "--name-only"
              ]))
  
          for diff_file in diff_files:
              # If the file was deleted in the commit we are reformatting, we need to delete it again
              if diff_file in deleted_files:
                  repo.rm([diff_file])
                  continue
  
              if "volk" in diff_file:
                  continue
              # The file has been added or modified, continue as normal
              file_contents = repo.show(["%s:%s" % (previous_commit, diff_file)])
  
              root_dir = os.path.dirname(diff_file)
              if root_dir and not os.path.exists(root_dir):
                  os.makedirs(root_dir)
  
              with open(diff_file, "w+") as new_file:
                  new_file.write(file_contents)
  
              repo.add([diff_file])
  
          # Create a new commit onto clang-formatted branch
          repo.commit(["--reuse-message=%s" % previous_commit])
  
          previous_commit_base = repo.rev_parse(["HEAD"])
  
      # Create a new branch to mark the hashes we have been using
      repo.checkout(["-b", new_branch])
  
      print("reformat-branch is done running.\n")
      print(
          "A copy of your branch has been made named '%s', and formatted with clang-format.\n"
          % new_branch)
      print("The original branch has been left unchanged.")
      print("The next step is to rebase the new branch on 'main'.")
function_tokens: def _reformat_branch ( clang_format , commit_prior_to_reformat , commit_after_reformat ) : try : clang_format = ClangFormat ( clang_format ) except NameError as e : print ( e ) return False if os . getcwd ( ) != get_base_dir ( ) : raise ValueError ( "reformat-branch must be run from the repo root" ) repo = Repo ( get_base_dir ( ) ) # Validate that user passes valid commits if not repo . is_commit ( commit_prior_to_reformat ) : raise ValueError ( "Commit Prior to Reformat '%s' is not a valid commit in this repo" % commit_prior_to_reformat ) if not repo . is_commit ( commit_after_reformat ) : raise ValueError ( "Commit After Reformat '%s' is not a valid commit in this repo" % commit_after_reformat ) if not repo . is_ancestor ( commit_prior_to_reformat , commit_after_reformat ) : raise ValueError ( ( "Commit Prior to Reformat '%s' is not a valid ancestor of Commit After" + " Reformat '%s' in this repo" ) % ( commit_prior_to_reformat , commit_after_reformat ) ) # Validate the user is on a local branch that has the right merge base if repo . is_detached ( ) : raise ValueError ( "You must not run this script in a detached HEAD state" ) # Validate the user has no pending changes if repo . is_working_tree_dirty ( ) : raise ValueError ( "Your working tree has pending changes. You must have a clean working tree before proceeding." ) merge_base = repo . get_merge_base ( commit_prior_to_reformat ) if not merge_base == commit_prior_to_reformat : raise ValueError ( "Please rebase to '%s' and resolve all conflicts before running this script" % ( commit_prior_to_reformat ) ) # We assume the target branch is main, it could be a different branch if needed for testing merge_base = repo . get_merge_base ( "main" ) if not merge_base == commit_prior_to_reformat : raise ValueError ( "This branch appears to already have advanced too far through the merge process" ) # Everything looks good so lets start going through all the commits branch_name = repo . get_branch_name ( ) new_branch = "%s-reformatted" % branch_name if repo . does_branch_exist ( new_branch ) : raise ValueError ( "The branch '%s' already exists. Please delete the branch '%s', or rename the current branch." % ( new_branch , new_branch ) ) commits = get_list_from_lines ( repo . log ( [ "--reverse" , "--pretty=format:%H" , "%s..HEAD" % commit_prior_to_reformat ] ) ) previous_commit_base = commit_after_reformat # Go through all the commits the user made on the local branch and migrate to a new branch # that is based on post_reformat commits instead for commit_hash in commits : repo . checkout ( [ "--quiet" , commit_hash ] ) deleted_files = [ ] # Format each of the files by checking out just a single commit from the user's branch commit_files = get_list_from_lines ( repo . diff ( [ "HEAD~" , "--name-only" ] ) ) for commit_file in commit_files : # Format each file needed if it was not deleted if not os . path . exists ( commit_file ) : print ( "Skipping file '%s' since it has been deleted in commit '%s'" % ( commit_file , commit_hash ) ) deleted_files . append ( commit_file ) continue if files_match . search ( commit_file ) : clang_format . format ( commit_file ) else : print ( "Skipping file '%s' since it is not a file clang_format should format" % commit_file ) # Check if anything needed reformatting, and if so amend the commit if not repo . is_working_tree_dirty ( ) : print ( "Commit %s needed no reformatting" % commit_hash ) else : repo . commit ( [ "--all" , "--amend" , "--no-edit" ] ) # Rebase our new commit on top the post-reformat commit previous_commit = repo . rev_parse ( [ "HEAD" ] ) # Checkout the new branch with the reformatted commits # Note: we will not name as a branch until we are done with all commits on the local branch repo . checkout ( [ "--quiet" , previous_commit_base ] ) # Copy each file from the reformatted commit on top of the post reformat diff_files = get_list_from_lines ( repo . diff ( [ "%s~..%s" % ( previous_commit , previous_commit ) , "--name-only" ] ) ) for diff_file in diff_files : # If the file was deleted in the commit we are reformatting, we need to delete it again if diff_file in deleted_files : repo . rm ( [ diff_file ] ) continue if "volk" in diff_file : continue # The file has been added or modified, continue as normal file_contents = repo . show ( [ "%s:%s" % ( previous_commit , diff_file ) ] ) root_dir = os . path . dirname ( diff_file ) if root_dir and not os . path . exists ( root_dir ) : os . makedirs ( root_dir ) with open ( diff_file , "w+" ) as new_file : new_file . write ( file_contents ) repo . add ( [ diff_file ] ) # Create a new commit onto clang-formatted branch repo . commit ( [ "--reuse-message=%s" % previous_commit ] ) previous_commit_base = repo . rev_parse ( [ "HEAD" ] ) # Create a new branch to mark the hashes we have been using repo . checkout ( [ "-b" , new_branch ] ) print ( "reformat-branch is done running.\n" ) print ( "A copy of your branch has been made named '%s', and formatted with clang-format.\n" % new_branch ) print ( "The original branch has been left unchanged." ) print ( "The next step is to rebase the new branch on 'main'." )