Почему этот флаг --cached указывает на разную память в разных командах git? - PullRequest
0 голосов
/ 22 апреля 2020

Почему git rm --cached удаляет файлы из "index" или "stage", но git ls-files --cached перечисляет файлы не из "index", а из текущего коммита.

Мне нужно использовать git ls-files --staged перечислить файлы в «индексе».

Я думал, что кэш, этап и индекс - это одно и то же. Почему этот флаг --cached, похоже, относится к разной памяти в разных командах.

1 Ответ

1 голос
/ 22 апреля 2020

Хотя на самом деле это не проблема программирования , это одна из классических c Git ошибок.

Некоторые команды Git принимают --index flags ( git apply в частности). Некоторые принимают --cached и --staged в качестве синонимов (в частности, git diff). Некоторые используют только --cached (git rm), а некоторые используют только --staged (git ls-files). Почему? (Примечание: ответы на этот тип вопросов обычно включают историю и / или философию.)

Как отметил phd в комментарии , «создание непротиворечивого пользовательского интерфейса не является [a Git] опора ".

Существует сущность Git, обычно хранящаяся в файле - .git/index - самая распространенная, - Git по-разному вызывает index * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * (иногда и довольно редко). Существует отдельная сущность, которая существует только во время выполнения внутри Git программ, которая также называется cache . Путаница между двумя именами объясняет, почему «кеш» теперь в основном зарезервирован для структуры данных в памяти. Таким образом, мы должны вызвать другой - материал на диске, который находится в .git/index или, возможно, в другом месте, index , чтобы указать, как он называется и где он находится, или область подготовки для ссылки на ее основную функцию.

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

Если вы делаете новый коммит, то в новом коммите есть ваше имя и адрес электронной почты в виде автор и коммиттер, «сейчас» (как определено часами вашего компьютера) в качестве отметок даты и времени, и любое сообщение журнала, которое вы предоставляете в качестве сообщения журнала. Родитель (и) новой фиксации устанавливаются автоматически Git в зависимости от ситуации. Некоторая дополнительная информация, такая как кодировка текста коммитов, строки подписи, подписи GPG и т. Д., Также может быть в метаданных. Так вот откуда взялись метаданные: в основном от вас, причем немного предоставлено самим Git. Но как насчет снимка ?

Git делает снимок, превращая набор файлов - имена файлов, режимы и содержимое - которые хранятся в индексе, в замороженный набор файлов, хранящихся в коммите. (Технически, каждый файл content сам по себе уже находится в хранилище в виде Git объекта BLOB-объекта , но мы видим это, только когда углубляемся в детали отдельных индексные записи.)

Мы проверяем некоторую начальную фиксацию, делая ее текущей, чтобы работать с ней: git checkout master или git switch master, для instace. Git копирует файлы выбранного коммита в индекс, так что промежуточная область - индекс, рассматриваемый как предлагаемый следующий коммит - совпадает с текущим коммитом. Git копирует файлы индекса в наше рабочее дерево, чтобы мы могли трогать и нюхать файлы или что бы мы ни делали с файлами, хранящимися в их обычной форме - файлы внутри фиксации находятся в специальном, только для чтения , Git - только форма, которую остальная часть системы не может использовать вообще.

Затем мы сворачиваем, разбрасываем и искажаем файлы рабочего дерева, к нашему сердцу , Когда мы закончим с этим и wi sh сделаем новый коммит, мы должны заменить индексные копии файлов. Использовать git add - самый простой способ: Git скопирует версию файла рабочего дерева обратно в индекс, заменив готовую к фиксации версию замороженного формата Git. Все файлы, которые мы не не заменяем здесь, остаются в той же форме, в которой они находились с тех пор, как мы извлекли их ранее. Так что это упорядочивает индекс - stage it, другими словами, - чтобы быть готовым к следующему коммиту.

Так вот откуда взялись names . Но почему флаги несовместимы? Единственный реальный ответ здесь - история. Термин stage появился позже. Имя index использовалось с самого начала. Это явно не такой уж и хороший термин: это слишком обобщенно c.

При индексировании: Меня не будут толкать, подавать, ставить отметки, индексировать, инструктировать, анализировать или пронумеровывать.
Подробнее об узнике

Тот факт, что индекс действует как область подготовки, вероятно, привел к термину область подготовки и флагам --staged - хотя на самом деле способ слияния явно предшествовал это. Во время конфликтующего слияния индекс расширяется от наличия одной копии каждого файла до наличия (до) трех . Три копии принадлежат трем различным коммитам, и они пронумерованы. Эти номера номера промежуточных слотов . Промежуточный слот № 1 предназначен для базы слияния, слот № 2 предназначен для файла «наш», а слот № 3 - для файла «их».

Вы разрешаете конфликт слияния, удаляя ненулевую промежуточную запись- записи с номерами слотов из индекса и вместо этого сохранение записи файла с нулевым временным интервалом для файла (или полное удаление всего, если предполагается, что файл не существует в новом коммите). Опять же, git add делает всю эту работу за вас, легкий путь: нет необходимости возиться с git update-index в наши дни.

Иногда предпринимаются попытки, как в git apply, отличить guish четко между "только то, что в индексе" и "что в индексе и рабочее дерево". Например, согласно документации git apply :

--index

Когда действует --check или при применении патча (который используется по умолчанию, когда ни один из параметров, которые отключают его, не действует), убедитесь, что исправление применимо к текущим записям файла индекса. Если файл для исправления в рабочем дереве не обновлен, он помечается как ошибка. Этот флаг также приводит к обновлению индексного файла.

--cached

Применить исправление, не касаясь рабочего дерева. Вместо этого возьмите кэшированные данные, примените исправление и сохраните результат в индексе без использования рабочего дерева. Это подразумевает --index.

То есть --index означает касание (изменение путем исправления) как индекса, так и рабочего дерева и --cached означает коснитесь только указателя . Но git ls-files и git diff не ничего не изменяют , поэтому им не нужно такое различие.

Действительно, я думаю, что оба термина не так уж хороши, но они имеют был определен таким образом на протяжении более десяти лет. Мы в значительной степени застряли с ними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...