7

考虑以下用例:

我正在本地分支上工作,而主分支上已经完成了重构。现在一些文件(类)已被重命名和/或移动到新位置。合并时,由于缺少类,我得到很多导入错误。

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

里面有A我用过的旧名字F--G--H--I

B--C--D--E文件中重构导致新的文件名在E. 这包括链式重命名,如

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

J由于我的分支上缺少重构,现在合并导致许多(编译)错误。(因为我仍然指path.to.File而不是final.package.FinalName

为了修复损坏的构建,我需要知道旧类的新名称。

是否有一个 git 命令来获取已应用于特定文件的所有重命名?

4

2 回答 2

1

Git 应该找到文件的重命名。但是,如果文件在该文件中有 50% 或更多的行更改,将不再被视为重命名。如果您愿意,可以更改此阈值。

这是执行此操作的命令:

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

它只会显示重命名。如果要将阈值更改为默认 50% 以外的其他值,只需将数字添加到 M 选项:

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

仅当内容更改不超过 10% 时才会认为文件已重命名

更新:

要跳过所有中间步骤,请改用 diff。Git 将为您遵循重命名:

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

当您在主题分支上时。

然后,您可以通过管道制作一堆 sed 指令来调整您的引用。

于 2012-04-17T15:52:56.607 回答
-1

我在网上找不到令人满意的答案,所以我写了一个(尴尬的)脚本来逐个浏览日志(通过重命名来重命名)

将脚本与上述示例一起使用可提供以下输出:

$ git history path/to/File.java

final/package/FinalName.java

我将脚本添加到我的并在我的全局 git 配置中~.bashrc添加了一个选项alias.history=!bash -ic 'git_file_history "$@"' -

#! /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";
}
于 2012-06-26T08:12:43.190 回答