为什么git不能识别以前在合并时检入的重命名 – 合并方向是否重要?

我刚刚经历了一个有点痛苦的过程,即在功能分支上重命名/重组和重构大型代码库.在此过程中,我进行了几次更改的增量签名,以确保git识别重命名.但是,现在我将这个功能合并到我的开发分支中,看起来
Git并没有“记住”这些重命名,而是将它们视为删除/添加.设置不同的重命名阈值似乎没有帮助.

git不应该从之前的提交中知道文件被重命名/移动了吗?

编辑
奇怪的是,如果我将dev合并到我的功能分支中,而不是反之亦然,git似乎会识别重命名.我最终做了这个,然后将dev重置为我的功能分支的顶部.在这种情况下,合并的方向是否重要?

最佳答案 git实际上并不跟踪重命名 – 它依赖于’重命名检测’算法来检测重命名,如
Git FAQ所述:

Git has to interoperate with a lot of different workflows, for example
some changes can come from patches, where rename information may not
be available. Relying on explicit rename tracking makes it impossible
to merge two trees that have done exactly the same thing, except one
did it as a patch (create/delete) and one did it using some other
heuristic.

On a second note, tracking renames is really just a special case of
tracking how content moves in the tree. In some cases, you may instead
be interested in querying when a function was added or moved to a
different file. By only relying on the ability to recreate this
information when needed, Git aims to provide a more flexible way to
track how your tree is changing.

However, this does not mean that Git has no support for renames. The
diff machinery in Git has support for automatically detecting renames,
this is turned on by the ‘-M’ switch to the git-diff-* family of
commands. The rename detection machinery is used by git-log(1) and
git-whatchanged(1), so for example, ‘git log -M’ will give the commit
history with rename information. Git also supports a limited form of
merging across renames. The two tools for assigning blame,
git-blame(1) and git-annotate(1) both use the automatic rename
detection code to track renames.

As a very special case, ‘git log’ version 1.5.3 and later has
‘–follow’ option that allows you to follow renames when given a
single path.

因此,如果您重构并重命名了一个文件,它与旧文件的相似性将非常小,结果状态或日志可能表示文件已被删除然后添加.

一些选项可能有助于检测重命名,即使通过重构:

> -M< n>

Detect renames. If n is specified, it is a threshold on the
similarity index (i.e. amount of
addition/deletions compared to the file’s size). For example, -M90% means git should consider a
delete/add pair to be a rename if more than 90% of the file hasn’t changed.

> -w

Ignore changes in amount of whitespace. This ignores whitespace at
line end, and considers all other
sequences of one or more whitespace characters to be equivalent.

> -B< n>

Break complete rewrite changes into pairs of delete and create.

-B很有用,因为它可以允许文件被视为重命名源,即使它们已被更改;例如,如果您将90%的foo.c移动到bar.c,它会检测重命名,但在foo.c中保留了一些函数.

点赞