Как я могу помешать мерзавцу думать, что я сделал переименование

#git

Вопрос:

У меня есть два файла index.html и template.html . Я переместил большую часть index.html в template.html , и теперь git думает, что я сделал переименование, когда я добавляю оба файла. Можно ли предотвратить это в конкретных случаях?

Комментарии:

1. Git на самом деле не хранит тот факт, что он думает, что вы сделали переименование. Фактическая база данных объектов хранит только полные моментальные снимки вашего проекта, и нет никакой концепции изменения/переименования/перемещения. Тот факт, что Git говорит, что вы переименовали файл, является результатом последующего анализа базы данных.

2. @JacobGroundwater О, я понимаю, так что это просто не имеет значения. Спасибо. 🙂

Ответ №1:

Почему Git Думает, Что Ваши Файлы Являются Копиями

Git отслеживает содержимое, а не имена файлов. В результате, если два файла имеют практически одинаковое содержимое, git подумает, что вы скопировали или переименовали файл. Если вы прочитаете git-log(1), вы узнаете:

Индекс сходства-это процент неизмененных строк, а индекс несходства-это процент измененных строк. Это округленное в меньшую сторону целое число, за которым следует знак процента. Таким образом, значение индекса сходства 100% зарезервировано для двух одинаковых файлов, в то время как 100% — ная несходность означает, что ни одна строка из старого файла не попала в новый.

Итак, если предположить, что ваш индекс сходства равен 100%, мерзавец подумает, что это копия. Лучше всего добавить разумное сообщение или заметку в журнале (подробнее см. git-примечания(1)), чтобы объяснить, что происходит, если вы не считаете, что git поступает правильно.

Корректировка индекса сходства

Вы также можете попробовать настроить значения, которые git использует для рассмотрения чего-либо как копии или переименования. В руководстве для git-log(1) говорится:

 -M[<n>], --find-renames[=<n>]

If generating diffs, detect and report renames for each commit. For
following files across renames while traversing history, see --follow. 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.

-C[<n>], --find-copies[=<n>]    

Detect copies as well as renames. See also --find-copies-harder.
If n is specified, it has the same meaning as for -M<n>.
 

Опять же, это не поможет вам, если файлы в основном похожи, но вы, безусловно, можете использовать эти значения, чтобы настроить, насколько они должны быть похожи, чтобы считаться копиями или переименованиями. Ваш пробег может отличаться.

Комментарии:

1. Просто хотел бы отметить, что этот ответ гораздо более полезен и описателен, чем любой из ответов на другой вопрос

2. Этот двухэтапный процесс перед фиксацией будет работать: git сбросит неоднозначный файл, git зафиксирует, git добавит неоднозначный файл, git зафиксирует.

Ответ №2:

Существует «принятый» ответ, но он не дает никакого намека на то, как ответить на вопрос.

Правильный ответ, полученный из git-log(1) и git-diff(1), таков:

    --no-renames
       Turn off rename detection, even when the configuration
       file gives the default to do so.
 

Комментарии:

1. Хотя это будет работать в некоторых случаях использования, первоначальный первоначальный вопрос был «Возможно ли предотвратить это [обнаружение переименования] в конкретных случаях?» Флаг, который вы используете, отключает его везде, когда он находится в ~/.gitconfig , или для всего текущего запуска, когда он находится в командной строке. Даже элементы с индексом сходства >=99% не будут рассматриваться как переименования, что обычно не соответствует ожиданиям людей и может нарушить принцип наименьшего удивления. Тем не менее, определенно существуют варианты использования флага, иначе его бы не существовало. Спасибо, что указали на это здесь!

Ответ №3:

Если вы находитесь в момент непосредственно перед фиксацией и «вам плохо, что git сошел с ума», затем просто отмените добавление неоднозначного файла, который, по мнению git, вы переименовали, выполните фиксацию, затем снова добавьте неоднозначный файл и зафиксируйте:

 git reset ambiguous_file_git_thought_you_renamed
git commit
git add ambiguous_file_git_thought_you_renamed
git commit
 

Это сработало для меня.

Дважды проверьте, не было ли переименования:

 git diff --name-status -C HEAD^^ HEAD
M       ambiguous_file_git_thought_you_renamed
M       original_file
 

«М» в начале означает измененный, «Р» означает Переименованный. Обратите внимание, что здесь нет переименованных.

Комментарии:

1. git commit Нужно ли второму иметь --amend флаг, чтобы включить изменение в тот же коммит? Я добавил флаг, и это сработало для меня, чтобы обойти обнаружение переименования.

2. Если они окажутся в одном и том же коммите, то в какой-то момент что-то решит, что это были переименования. Единственный способ по-настоящему предотвратить это-навсегда сохранить их в отдельных обязательствах.

Ответ №4:

Если вы изменили файлы A, B и C; и удалили файлы D, E и F; есть вероятность, что git решит, что D переименован в A или что-то подобное.

Самым простым решением является разделение изменений и удалений файлов на две фиксации.