Search code examples
gitrefactoringrenamestaginggit-stage

Simple command to stage all files that were renamed without modifications


When I rename an entire folder or do refactoring, I think it's good practice to isolate the rename operation on its own separate commit. If I mix it with other pending modifications, I'll only complicate the verification of the commit. So the commit should have only path rename operations with no other modifications, except when they are renamed references inherent to the refactoring operation (but I would manually stage those).

Is there a simple git command (or shell script / function that I could add to ~/.bash_aliases) that I can use to stage all files that were renamed with no other modifications, and only those?

For simplicity, you may assume nothing else is staged, so you could make it 2 step like:

  1. stage all files
  2. unstage all files that have modifications other than just path renaming

How would I do that?


Solution

  • git status --porcelain=v2 distinguishes between normal changes and renames/copies.
    You can add this to bash_aliases:

    function gitStageRenamed() {
      git add -A &&
      git status --find-renames=100% --porcelain=v2 |
      grep ^1 | cut -d' ' -f 9- | xargs -rd'\n' git reset
    }
    

    This takes all normal edits (lines starting with 1), gets the paths, and passes them to git reset.

    If you are not using GNU xargs (Mac), get rid of the -rd'\n', although it will not be as robust (won't handle filenames with spaces and may run git reset even if there are only renames).