Примечание: даже обновления Git может быть недостаточно, только до Git 2.19 (Q3 2018), так как "git merge --abort
" и т. Д. Не очищали вещи должным образом, когда в определенном порядке присутствовали конфликтующие записи в индексе в определенном порядке. в конфликтах D / F.
Это было исправлено с Git 2.19.
read-cache
: исправление обработки конфликтов файлов и каталогов в read_index_unmerged()
read_index_unmerged()
имеет две цели:
- вернуть 1, если есть какие-либо необъединенные записи, 0 в противном случае
- сбрасывает любые записи более высокого уровня до уровня # 0
Есть несколько абонентов read_index_unmerged()
, которые проверяют возврат
значение, чтобы увидеть, если оно ненулевое, все из которых затем die()
, если это условие
встретил
Для этих вызывающих абонентов сброс высокоуровневых записей до этапа #0
является пустой тратой ресурсов, и лучше сразу вернуться к первому нефиксированному входу.
Но это, вероятно, лишь незначительная разница и не является предметом этой серии.
Оставшиеся вызывающие абоненты игнорируют возвращаемое значение и вызывают эту функцию для побочного эффекта сброса записей более высокого уровня до этапа № 0.
Как упомянуто в commit e11d7b5 («reset --merge: исправление нефиксированного регистра», 2009-12-31, Git 1.7.0),
only причина, по которой мы хотим сохранить ранее непогруженную запись в индексе на этапе # 0, заключается в том, что мы не забываем тот факт, что у нас есть соответствующий файл в рабочем дереве, чтобы возможность удалить его, когда дерево, к которому мы возвращаемся, не имеет пути.
Фактически, до commit d1a43f2 ("reset --hard / read-tree --reset -u:
удалить необработанные новые пути ", 2008-10-15, Git 1.6.0.4), read_index_unmerged()
сделал просто
Немедленно удаляйте необработанные записи из кэша, но это приводило к нежелательному эффекту оставления вокруг неотслеживаемых файлов в дереве от прерванных слияний.
Итак, это целевое назначение этой функции.
Проблема заключается в том, что при наличии конфликтов каталогов / файлов попытка добавить файл в индекс на этапе 0 завершается неудачно (поскольку в пути все еще есть каталог),
и функция возвращается рано с кодом возврата -1 для обозначения ошибки .
Как отмечалось выше, ни один из вызывающих абонентов, которые хотят, чтобы поведение drop-to-stage-0 не проверяло состояние возврата, тем не менее, это означает, что все оставшиеся необъединенные записи остаются в индексе, и вызывающие абоненты продолжают предполагать иначе.
Пользователи видят ошибки в виде:
error: 'DIR-OR-FILE' appears as both a file and as a directory
error: DIR-OR-FILE: cannot drop to stage #0
и, возможно, также сообщения о других необработанных записях, которые пришли лексикографически позже, чем любое имя пути, являющееся как файлом, так и каталогом. Google находит несколько обращений в поисках этих сообщений, предполагая, что, возможно, есть пара человек, которые обращались к этому, кроме меня.
К счастью, многократный вызов git reset --hard
поможет обойти эту ошибку.
Поскольку вся цель здесь состоит в том, чтобы просто поместить запись временно в индекс, чтобы можно было удалить любой связанный файл в рабочей копии, мы можем просто пропустить DFCHECK и разрешить как файл и каталог для отображения в индексе .
Временное одновременное появление записей каталога и файлов в индексе будет удалено вызывающими программами путем вызова unpack_trees()
, что исключает эти не объединенные записи, отмеченные флагом CE_CONFLICTED
, из полученного индекса, прежде чем они попытаются записать индекс где-либо.