1

I am writing a script that uses git. It needs to know the old file path and the new file path of all renamed directories and files.

Example of what I want to do: git diff --find-renames-only someGitHash someGitHash Then I would like to see a list like:

rename old/path/old-file-name.extension->new/path/new-file-name.extension

or

rename from source/README.md
rename to documentation/README.md

Or something like this as long as it has the old file name with the old directory path and the new file name with the new directory path for each .

I have messed around and searched everywhere so far the closest thing I could find is git diff --find-renames

git diff --find-renames gives me the data I want but with way too much data for each file. It is definitely not something I want to deal with and parse through. Some of the git repos I am working with could have thousands of file/folder renames...

Example:

...tons more data that I do not want to parse through
rename from source/README.md
rename to documentation/README.md
...tons more data including diffs of files before and after... 

this pattern continued for each file...

How do I list all file and directory renames between two git commits without the extra data?

Any help would be much appreciated, Thanks!

Tim
  • 1,606
  • 2
  • 21
  • 42
  • 2
    If `git diff ` produces what you want, but too much, trim it down: `git diff --name-status `; add `--diff-filter=R` to show only `R`-status results. – torek May 05 '20 at 01:20
  • problem with `git diff ` is that it's only going to work if the rename can be detected by comparing the blobs of `` and ``. For example, `git diff ~` may detect the rename but `git diff ` may not, if `` introduces sufficient changes :/ – CervEd Dec 23 '22 at 15:02
  • this might help: https://stackoverflow.com/questions/12850030/git-getting-all-previous-version-of-a-specific-file-folder – Ben Creasy Jan 03 '23 at 23:24

1 Answers1

4
git log --name-status <start_commit>..<end_commit> | grep ^R

This will show you a history of renames from newest to oldest.

The output looks like this:

R100    the-5-min/.watchmanconfig       the-10-min/.watchmanconfig
R100    the-5-min/App.tsx       the-10-min/App.tsx
R085    the-5-min/app.json      the-10-min/app.json
R100    the-5-min/assets/examples/accordion.png the-10-min/assets/examples/accordion.png
R100    the-5-min/assets/examples/angular-gradient.png  the-10-min/assets/examples/angular-gradient.png

The first letter is the type of change (see --diff-filter for the details of the different change types), and the number is the degree of similarity between commits. The first filename listed is the old filename, second filename is the new one.

linqo
  • 617
  • 4
  • 16
  • This is great thank you! Is there a way to only see the changes between two commits? – Tim May 05 '20 at 14:17
  • Edited my answer to address your question. – linqo May 05 '20 at 14:25
  • Do you know of a way to do this but only target renamed directories? – Tim May 06 '20 at 16:22
  • 1
    Unfortunately I don't. The tough thing is that directories themselves are not checked into git, even if files within them are. The way I'd approach that problem is to use `xargs` and `cut` to test if each component in a path is a directory or not, but that would only test for changes to directories that currently exist. Another approach could be to loop over the directories in the git path using `find` and check for their git histories. Good luck. – linqo May 06 '20 at 22:05