Git считает, что файл в каталоге с символическими ссылками был удален после воссоздания символической ссылки, как я могу это исправить? - PullRequest
0 голосов
/ 07 марта 2020

В моем репозитории есть каталог с символическими ссылками, который ссылается на файлы в других местах файловой системы. По какой-то причине символическая ссылка порой прерывается, и она превращается в обычную пустую папку. Поэтому я удалил пустую папку и заново создал символическую ссылку с ln -s ../../ ext, которая, похоже, сработала, так как я могу просмотреть эту папку и просмотреть ее содержимое. Но когда я запускаю git status, кажется, что все файлы, которые должны быть видны в папке ext, отсутствуют. Как я могу заставить git увидеть, что они снова там, в каталоге с символическими ссылками?

Кстати, это на Ubuntu 18.

1 Ответ

0 голосов
/ 08 марта 2020

Ваша настройка нечетна, потому что Git не следует за символическими ссылками, просто хранит их.

То есть, если у вас есть символ c link ext -> ../.. и вы запускаете git add ext, Git создает в индексе запись с режимом 120000 (символическая ссылка) для хранения содержимого BLOB-объекта ../... При фиксации будет создан коммит, который при извлечении создаст символ c ссылка ext, указывающий на ../... Git не будет хранить какие-либо файлы в ext при сохранении этой ссылки c.

Если, с другой стороны, у вас есть существующий коммит, который содержит файлы с именами ext/foo и ext/bar, и вы клонируете этот репозиторий при этом коммите или извлекаете этот коммит в новое и иначе пустое рабочее дерево, Git увидит это для записи в файлы с именами ext/foo и ext/bar ваша ОС требует, чтобы ext существовал как каталог. Поэтому он создаст пустой каталог ext, в котором он затем создаст файлы foo и bar в соответствии с требованиями вашей ОС, чтобы создать файлы, которые Git просто названы ext/foo и ext/bar. Эти два имени, ext/foo и ext/bar, теперь будут в индексе, поэтому следующий сделанный вами коммит также будет содержать эти два файла.

Звучит как вы:

  1. клонировал репозиторий (возможно, с git clone --no-checkout?);
  2. вручную создал символическую c ссылку в рабочем дереве с именем ext, указывающую на какой-то существующий каталог (возможно, один с некоторыми файлами) внутри него);
  3. убежден git checkout создать ext/foo и ext/bar без предварительного удаления символа c ссылка ext и замены его каталогом ext.

Это не поддерживаемый режим работы 1 , и вы не должны удивляться, если что-то пойдет не так.


1 Это ведет к безопасности проблемы: Git предназначено для того, чтобы не записывать какие-либо файлы "вне" области рабочего дерева, а запись в файлы "под" символьной c ссылкой на каталог вне рабочего дерева позволит этому произойти. Вместо того, чтобы тщательно ограничивать использование ссылки символами c, Git, как правило, просто не хранит файлы «за пределами» какой-либо ссылки, хотя это, вероятно, возможно благодаря осторожным манипуляциям с индексом и, на уровне ОС, файловая система, в которой находится ваше рабочее дерево, чтобы обмануть Git вручную.

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