7

I'm lost in a repo maze with a bunch of files that were readded while their older version was renamed because of a not-so-good rebase that was made.

Anyway, I want to list all the files that at some point were renamed, that is, list all renamed files from all commits.

Roberto
  • 11,557
  • 16
  • 54
  • 68
  • `git log --follow` from [this question](http://stackoverflow.com/questions/5743739/how-to-really-show-logs-of-renamed-files-with-git) – johnMa Dec 19 '13 at 02:36
  • sorry, no, I want to list *all* files that were changed in all commits, `--follow` only works for a single file. – Roberto Dec 19 '13 at 02:59
  • It sounds like you are in an icky situation. Are you able to use `git reflog` (or a branch, or something) prior to the rebase and redo your commits from there so you aren't in this position? – James Dec 19 '13 at 04:07

3 Answers3

4

Would this suffice?

git whatchanged -M5 --summary | grep rename | grep '=>'

Here is a modified version which will do renamed and deleted files:

git whatchanged -M5 --summary | grep -E 'rename.*=>|delete mode'

This will give you all renames from the HEAD of your current branch and it's ancestry including merged parents up to the very first commit. The -M5 will have files that are similar by 50% or more reported as a rename; this may be to low of a percentage but you can change it (The 5 is read as .5, or 50% so you could change it to M8 for 80%). Be warned, it will take a long time if there are a lot of commits.

I suggest you limit the range of commits such as:

git whatchanged -M5 --summary <commit-id>..HEAD | grep rename | grep '=>'

As far as I can tell you will need to start with a commit, I am not sure how you could get a comprehensive list of renamed files across all branches and tags at once. If you have divergent branches you want to check, or branches with independent commit histories in a single repo, you will need to run the suggested command on each branch.

James
  • 1,754
  • 14
  • 22
1

You should be able to get that info from the logs using --diff-filter option. The filter for renamed files is R, and D for deleted files.

Renamed files:

git log --summary --pretty='format:' --diff-filter=R

Deleted files:

git log --summary --pretty='format:' --diff-filter=D

Renamed + deleted files:

git log --summary --pretty='format:' --diff-filter=RD
Gongora
  • 595
  • 6
  • 10
0

Background

It's important to note that renames work in git are special.

Due to the fundamental nature of how git works, renames are not recorded into the version control system. They are reconstructed after the fact, in the same way that diff hunks are, by comparing the binary content of files between revisions.

This means that file_a and file_b, are considered "renamed" between two revisions if file_a is deleted, file_a is added and they are "similar" enough. (I believe the default is 50%). Note that this means finding renames requires a bit more computation.

It also means that renames can often only be detected by walking the entire range of revisions. Unless, the rename is basically the only change in the range, say HEAD and HEAD~100, in such case it can also be detected using git diff --name-status --diff-filter=R.

How to list all renames in current branch

You can't use git-rev-list for this, you need to use git-log.

git log --name-status -M90%\
 --diff-filter=R --pretty=format: |
  sed\
  -e '/^$/{N;s@^\n$@@}'\
  -e 's@\(^\n\{0,1\}\)R[0-9]\{3\}\t@\1@'
  • --name-status, --pretty=format: just display the old name <tab> new name, no subject etc. of regular git-log.
  • -M90%, how similar counts as difference -M100% for identical (only renamed).
  • --diff-filter=R, only show renames
  • sed massage the output
    • -e '/^$/{N;s@^\n$@@}' strip output from commits with no renames (2x+ \n)
    • -e 's@\(^\n\{0,1\}\)R[0-9]\{3\}\t@\1@', massage the output to old_name <tab> new_name

Example

Running in the Git projects repository.

$ git log --name-status -M100%\
 --diff-filter=R --pretty=format: \
  v2.38.0..v2.39.0 |
  sed\
  -e '/^$/{N;s@^\n$@@}'\
  -e 's@\(^\n\{0,1\}\)R[0-9]\{3\}\t@\1@' |
  cat -A
fuzz-commit-graph.c^Ioss-fuzz/fuzz-commit-graph.c$
fuzz-pack-headers.c^Ioss-fuzz/fuzz-pack-headers.c$
fuzz-pack-idx.c^Ioss-fuzz/fuzz-pack-idx.c$

you can see that a couple of files were moved to oss-fuzz/ directory, between git versions 2.38.0 and 2.39.0.

CervEd
  • 3,306
  • 28
  • 25