Почему `git checkout <branch> <file> `внести изменения?

Если я начну с чистого рабочего дерева и запущу git checkout <branch> <file>, где <branch> имеет другую версию этого файла, и в итоге я получаю поэтапное, а не поэтапное изменение.

В чем причина этого? Это только для согласованности с другими командами, такими как git mv, которые, как вы ожидаете, будут вносить изменения? Это для удобства при использовании git checkout для разрешения конфликтов слияния? Или есть другое обоснование?

Мне это кажется немного странным, поскольку простое использование git checkout <branch> <file> не дает никаких указаний на то, планирую ли я внести изменение.

7 голосов | спросил Luke 24 Maypm17 2017, 18:58:06

1 ответ


0

Это действительно деталь реализации, которую авторы Git решили пропустить.

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

Когда вы git checkout целый коммит, это то, что вам нужно в любом случае. Таким образом, внутреннее ограничение - сначала копировать в индекс, а затем только в рабочее дерево - было плюсом. Таким образом, этот механизм, сначала копирование в индекс, а затем только в рабочее дерево, было внедрено в реализацию. Затем, в конце концов, пользовательский интерфейс git checkout получил возможность извлекать один отдельный файл или небольшое подмножество файлов. и он продолжал делать это через индекс. Детали реализации стали документированной функцией.

Обратите внимание, что иногда индекс используется в качестве вспомогательной области во время конфликтующего слияния. В этом случае для некоторого файла F может быть до трех записей в пронумерованных слотах 1 (базовый), 2 (--ours) и 3 (--theirs) вместо одной записи в обычном слоте -нуль. Когда это так, вы можете извлечь любую из трех записей слотов индекса в рабочее дерево, не нарушая индекс. Но если вы используете git checkout для извлечения файла из какого-либо другого коммита или дерева, Git копирует файл в индекс и записывает его в слот ноль. Это имеет побочный эффект удаления слотов с большими номерами, разрешения конфликта слияния!


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

2 Вы по-прежнему можете использовать этот рабочий процесс, используя git read-tree для копирования дерева в индекс, затем используйте git checkout-index, чтобы скопировать индекс в рабочее дерево. Изначально Git состоял из набора сценариев оболочки, таких как git-checkout, обернутых вокруг некоторых фундаментальных C-кодированных фрагментов, таких как git-read-tree. (Все имена были написаны через дефис, как это, и не было никакой команды git.)

ответил torek 24 Maypm17 2017, 22:54:48

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132