Why is it not recognized git, previously noted during renaming during merging - does it make sense to combine the direction?

I just went through a somewhat painful process of renaming / reorganizing and reorganizing a large code base on a function branch. During the process, I did incremental checks with slight modifications to ensure that git recognized renames. However, now when I merge this function into my development branch, it seems that git does not β€œremember” these renames and treats them as remove / add. Setting different rename threshold values ​​does not help.

Shouldn't git know from the previous commit that the files were renamed / moved?

EDIT What is strange is that if I combine dev into my function branch, instead of the other way around, git seems to recognize renames. I finished this and then dumped dev to the top of my function branch. In this case, does the direction of the merger matter?

+4
source share
2 answers

git does not actually track renames - it uses a rename detection algorithm to detect renames, as stated in the Git FAQ :

Git must interact with many different workflows, for example, some changes may come from patches where renaming information may not be available. Relying on explicit renaming tracking makes it impossible to merge two trees that did the same, except one did it as a patch (create / delete), and one did it using some other Heuristic.

In the second note, renaming is actually just a special case of tracking the movement of content in a tree. In some cases, you may instead be interested in requesting when a function was added or moved to another file. Only by relying on the ability to recreate this when necessary, Git aims to provide a more flexible way to track tree changes.

However, this does not mean that Git does not support renaming. diff in Git supports automatic rename detection; it is included by the '-M' switch in the git -diff- * family of commands. The rename detection mechanism is used by git -log (1) and git -whatchanged (1), for example, 'git log -M' will give a history fix with the renaming of information. Git also supports limited form merging between renames. Two guilty detection tools, git-blame (1) and git -annotate (1) both use automatic rename detection code to track renames.

As a special case of "git log" version 1.5.3 and later versions --follow, which allows you to rename when a single path.

Thus, if you edit and rename a file, its similarity to its old file will be very small, and as a result, status or log may indicate that the file has been deleted and added.

Several parameters can help detect renames even through refactoring:

  • -M<n>

    Rename Detection. If n is specified, this is the threshold for the similarity index (i.e., the number of additions / deletions compared to the file size). For example, -M90% means Git, you should consider deleting / adding a pair to rename if more than 90% of the file has not changed.

  • -w

    Ignore changes in the number of spaces. This ignores the spaces at the end of the line, and considers all other sequences of one or more space characters, which should be equivalent.

  • -B<n>

    Break Complete the rewriting of the changes to the delete and create pairs.

-B is useful because it allows you to allow files as rename sources, even if they have been changed; for example, it detects renaming if you moved 90% from foo.c to bar.c but left some functions in foo.c

+2
source

You will probably lose the foul of git configuration settings: merge.renameLimit

This option is pretty low by default (compared to large codebases) and will not try to detect renames if you merge too many files, fearing that it will be slow. It is possible that the merge in one direction goes beyond the limit, and in the other direction there is, therefore, the strange behavior of detecting renaming.

Try to increase the limit by

 git config merge.renameLimit 9999 

and try again.

0
source

Source: https://habr.com/ru/post/1435427/


All Articles