#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 или что-то подобное.
Самым простым решением является разделение изменений и удалений файлов на две фиксации.