#linux #git #symlink
#linux #git #символическая ссылка
Вопрос:
Наш проект Laravel использует символические ссылки. Недавно, когда я попытался извлечь информацию из работы моего коллеги, я получил это сообщение:
CONFLICT (modify/delete): resources/lang/en/validation.php deleted in HEAD and modified in a262067feb430a072c1d3abf2ec500150212ff0f. Version a262067feb430a072c1d3abf2ec500150212ff0f of resources/lang/en/validation.php left in tree.
error: failed to symlink 'resources/lang/en/validation.php': File name too long
При попытке git rm файл, мне говорят, что он не существует и удаляется в HEAD. Затем, когда я вытаскиваю, я получаю то же сообщение, что и выше. При попытке доступа к touch
файлу и git add
файлу, фиксации и последующего извлечения (чтобы перенести мои изменения в ту же ветку) я получаю аналогичное сообщение об ошибке:
CONFLICT (content): Merge conflict in resources/lang/en/validation.php
CONFLICT (modify/delete): resources/lang/en/auth.php deleted in HEAD and modified in a262067feb430a072c1d3abf2ec500150212ff0f. Version a262067feb430a072c1d3abf2ec500150212ff0f of resources/lang/en/auth.php left in tree.
error: failed to symlink 'resources/lang/en/auth.php': File name too long
Я попытался пропустить-worktree файл, предположим -изменить файл и изменить настройку конфигурации git git config --local core.longpaths true
, чтобы разрешить длинные пути. Ни один из них не сработал. Я думаю, что это связано с символической ссылкой, но я еще не запустил скрипт, и поэтому я не знаю, как это мешает использовать git.
Когда я пытаюсь запустить символическую ссылку, я получаю это сообщение об ошибке:
error: unable to create symlink resources/lang/en/auth.php: File name too long
error: unable to create symlink resources/lang/en/validation.php: File name too long
Короче говоря, я не могу git pull и, следовательно, не могу git push. Каково решение? Я не хочу git push force
этого.
Комментарии:
1. Можете ли вы отредактировать свой вопрос, чтобы показать результат
git show a262067feb430a072c1d3abf2ec500150212ff0f:resources/lang/en/validation.php
? Кроме того, какую файловую систему вы используете и какую ОС использует ваш коллега?2. Большое вам спасибо за поддержку и помощь в решении этой проблемы, я думаю, у меня все хорошо. Я думаю, я понял, как ответить, потому что я отменил его, просмотрев историю git. Похоже, он пытался создать символическую ссылку из содержимого внутри файла вместо имени файла, состоящего из тысяч символов, поэтому, возможно, сценарий символьной ссылки был плохим. Что бы сделал git show?
Ответ №1:
Запуск git pull
— это просто выполнение двух команд Git:
- Сначала
git pull
выполняетсяgit fetch
. При этом будут получены любые новые коммиты, необходимые для второй команды. - Во-вторых,
git pull
выполняется… ну, это может быть сложно. Однако вы запускаете его по умолчанию:git merge
.
Обычно при git pull
сбое одна из этих двух команд, которые он запускает, является той, которая на самом деле завершилась с ошибкой. Вторая команда чаще завершается с ошибкой, если у вас нет особенно слабого интернет-соединения. В вашем случае git merge
это сбой.
Слово failed обычно слишком сильно, на самом деле. Большинство слияний на самом деле не завершаются сбоем. Они просто останавливаются в середине операции из-за конфликта (или двух конфликтов, в вашем конкретном случае). Но ваше слияние немного особенное. У него действительно есть внутренний сбой, который повторяется несколько раз:
error: unable to create symlink resources/lang/en/auth.php: File name too long error: unable to create symlink resources/lang/en/validation.php: File name too long
Это происходит потому, что ваша ОС устанавливает жесткое ограничение на длину цели символической ссылки. Как вы нашли:
Похоже, он пытался создать символическую ссылку из содержимого внутри файла вместо имени файла…
Внутренние ограничения Git намного больше, чем у вашей ОС.
Символическая ссылка — это просто данные на одном уровне, и именно так Git стремится сохранить их (как объект blob, но с mode 120000
, а не с обычным файловым режимом 100644
or 100755
). На другом уровне данные будут интерпретироваться как имя файла, и это имя файла, как правило, имеет ограничение по длине, например, 1024 или 4096 байт.
Что бы сделал git show?
git show
содержимое символьной ссылки будет выдаваться при указании на объект символьной ссылки.
$ git hash-object -w -t blob /usr/share/misc/termcap
d305cd8e161ecc8a78b0485d1926b9600efc6cb7
$ git update-index --add --cacheinfo 120000,d305cd8e161ecc8a78b0485d1926b9600efc6cb7,crazy
$ git commit -m "add crazy-long symlink"
[master dbb6e35] add crazy-long symlink
1 file changed, 4725 insertions( )
create mode 120000 crazy
Обычные инструменты больше не будут работать с этим репозиторием (который я создал только для хранения этой безумно длинной символической ссылки):
$ git log | sed 's/@/ /'
commit dbb6e35967041fa4b03812866999ea0acd640dce
Author: Chris Torek <chris.torek gmail.com>
Date: Sun Nov 15 19:52:05 2020 -0800
add crazy-long symlink
commit c6e238c122dcd41410e7fdcfaa47ac112e935a35
Author: Chris Torek <chris.torek gmail.com>
Date: Sun Nov 15 19:51:58 2020 -0800
initial commit
$ git checkout HEAD^
Это работает нормально, но попытка проверить вторую фиксацию завершается неудачей:
$ git checkout master
error: unable to create symlink crazy: File name too long
D crazy
Previous HEAD position was c6e238c initial commit
Switched to branch 'master'
На данный момент происходит то, что Git просто полностью удаляет символическую ссылку из рабочего дерева. Вот почему он находится в состоянии D
. Вы все еще можете работать с репозиторием, но вы не можете использовать обычные инструменты обычным способом.
С помощью вашего слияния вы можете полностью (безопасно) удалить плохие символические ссылки, создать правильные (хорошие) и добавить их.