Как мне обновить локальное репо с "без изменений" (конец строки)

Я работаю в команде, в которой все, кроме меня, работают с Mac. Я работаю с Windows 10. Я клонировал удаленный командный репозиторий и работал с ним, когда мы поняли, что были проблемы с CRLF. Я изменил опцию git, но теперь я хочу снова обновить репозиторий, но изменений не обнаружено, поэтому я не знаю, как вывести тот же текст, что и у меня, с правильным концом строки во все файлы репозитория.

Заранее спасибо.

1 ответ

Решение

Ответ, буквально, удалить все файлы и затем проверить их снова:

git rm -r -- .          # remove everything
git checkout HEAD -- .  # check everything out again

(Примечание: пример здесь использует --, который не требуется для имени .: это необходимо, только если имя вашего файла выглядит как имя ветви или опция команды. Это хорошая привычка использовать его постоянно, так что если вы хотите проверить файл с именем master позже вы просто автоматически пишете git checkout -- master и не случайно напиши git checkout master, что, очевидно, делает что-то другое.)

Почему вы должны удалить в первую очередь

Здесь есть довольно простое раздражение Git, которое заключается в том, что Git пытается быть эффективным. Используя немного более короткую команду, git checkout -- . иначе он будет делать то, что вы хотите, но Git сравнивает то, что находится в вашем index / staging-area / cache 1, с тем, что находится в вашем рабочем дереве. Git использует аспект "кэша" индекса, чтобы ускорить это, зная, что индекс индексирует / кэширует содержимое рабочего дерева, так что, если ничего не изменилось в индексе и рабочем дереве, версия рабочего дерева каждого файла автоматически правильно соответствует индексной версии этого же файла.

Краткое описание индекса заключается в том, что именно здесь вы строите свой следующий коммит. Вот почему у него есть область подготовки имени : вы "вставляете" файлы в него, и когда вы делаете коммит, новый коммит использует все, что находится на этом этапе, чтобы сделать снимок. Это в основном никогда не пусто, хотя (кроме как после нашего git rm -r -- . выше!): он начинается с каждого файла в текущем коммите. Позже вы будете использовать git add заменить индексную версию файла более новой версией.

Git в основном относится к коммитам, и каждый коммит хранит полный снимок каждого файла - не изменения с предыдущей версии, а только весь файл, неповрежденный, но сжатый. Копии, которые находятся в коммитах, находятся в этом специальном сжатом формате Git-only и доступны только для чтения, поскольку их нельзя изменить. Копия в индексе изначально является просто заменяемой версией копии, которая находится в коммите, и хранится с использованием всего нескольких десятков байтов, потому что это действительно версия в коммите, пока вы не перезапишите копию индекса новой версией., Таким образом, индексная копия также имеет специальный формат Gitty, который бесполезен для большинства программ и подходит только для самого Git.

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

Вот хитрая часть: вся специальная обработка конца строки происходит, когда файлы переходят из индекса в рабочее дерево или из рабочего дерева в индекс. Так git checkout -- <file>, который извлекает один файл из индекса в рабочее дерево, повторно выполняет обработку конца строки при создании файла, с которым вы будете работать. Ваше возможное git add -- <file> отменяет любую специальную обработку конца строки при сжатии файла в специальный формат Git-only для вставки его в индекс.

Но, как отмечалось выше, Git пытается быть эффективным. Индекс содержит не только копию файла, но и информацию о файле, чтобы помочь Git быстро выяснить, есть ли какая-либо разница между копией в индексе и копией в рабочем дереве. Если Git только что извлек файл, Git точно знает, что копия в рабочем дереве совпадает с копией в индексе.

Если вы измените свою обработку конца строки, вы измените способ, которым Git будет извлекать файл из индекса в рабочее дерево. Это означает, что копия в рабочем дереве больше не действительна. Это как раз и вызывает раздражение: Git не понимает, что копия рабочего дерева больше не действительна. Он считает, что он все еще идеально подходит, и не беспокоится о том, чтобы извлечь файл снова, чтобы не тратить время.

Это напрасно тратит ваше время, потому что теперь вам нужно что-то делать (например, удалять файл), чтобы заставить Git что-то сделать (повторно извлечь файл). git rm -r -- . удаляет каждый файл, как из рабочего дерева, так и из индекса, который находится в вашем текущем каталоге / папке (.), а затем git checkout HEAD -- . повторно извлекает каждый такой файл из текущего коммита в индекс и в рабочее дерево. Это подчиняется новой настройке конца строки и возвращает вам файлы в нужной форме.

Вам нужно сделать это только при изменении настроек конца строки, когда вы изначально настраиваете Git. Так что это своего рода разовая сделка - она ​​не так болезненна, как это описание звучит. Но я бы сказал, что это ошибка.


1 Это три разных имени для одной вещи, которые отражают ее огромную важность (это очень важно) или ее множественные разные роли (у нее несколько ролей), или потому что первое имя, которое использовалось, "index", таково плохое имя.:-)

Другие вопросы по тегам