How to find the new path of a renamed file whose original name is known?

一笑奈何 提交于 2019-12-21 12:23:14

问题


Consider following usecase:

I'm working on my local branch while refactoring has been done on the main branch. Now some files (classes) have been renamed and/or moved to new locations. When merging i get lots and lots of import-errors due to missing classes.

--A--B--C--D--E-- (master)
   \           \
    F--G--H--I--J  (topic)

In A there are the old names wich i used in F--G--H--I.

In B--C--D--E the files are refactored resulting in new file names in E. This includes chained renames like

   B: path/to/File.java              
-> C: path/to/BetterName.java
-> D: better/package/BetterName.java 
-> E: final/package/FinalName.java

Now merging results in J with many (compilation) errors due to the missing refactorings on my branch. (Because i still refer to path.to.File instead of final.package.FinalName

In order to fix the broken build, i need to know the new names for the old classes.

Is there a git command to get all the renames that have been applied to a particular file?


回答1:


Git should find the renames of the files. However, if the file has had 50% or more lines change in that file, it will no longer be considered a rename. You can change this threshold if you wish.

Here is the command to do it:

git log -M --diff-filter=R --stat

It will only show you the renames. If you want to change the threshold to something else other than the default 50%, you can just add the number to the M option:

git log -M90 --diff-filter=R --stat

will only consider a file as renamed if the contents have changed by no more than 10%

UPDATE:

To skip all the intermediate steps, use diff instead. Git will follow the renames for you:

git diff -M --diff-filter=R --name-status ..master | cut -f2-

when you are on your topic branch.

You can then pipe this to make a bunch of sed instructions to adjust your references.




回答2:


I couldn't find a satisfying answer on the web, so i've wrote a (awkward) script to go through the logs one by one (renaming by renaming)

Using the script with above example provides the follwing output:

$ git history path/to/File.java

final/package/FinalName.java

I added the script to my ~.bashrc and added a the option alias.history=!bash -ic 'git_file_history "$@"' - to my global git config

#! /bin/sh
### Takes a filename as parameter ($1)
### Echoes all filenames related to $1
function git_file_history() {
        loc_var=$1;
        old=""
        while [ "$loc_var" != "$old"  ] && [ "$loc_var" != "" ]
        do
                old=$loc_var;
                #echo $loc_var;
                hashes=$(git log --format="%P %H" -1 --follow --  $loc_var);
                status=$(git diff --name-status --find-renames $hashes | grep $loc_var);
                awks=`echo $status | awk '{print $3}'`
                loc_var=$awks;
        done 
        echo "$loc_var";
}


来源:https://stackoverflow.com/questions/10192285/how-to-find-the-new-path-of-a-renamed-file-whose-original-name-is-known

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!