Git: невозможно создать символическую ссылку (имя файла слишком длинное)
Я перенес проект из Linux в Bitbucket, а затем клонировал его в Windows. Оказалось, что были две символические ссылки, которые появились в Windows как текстовые файлы. Поскольку я знал, куда они должны указывать, я заменил их копиями файлов назначения, зафиксировал и отправил.
Теперь репозиторий Bitbucket выглядит нормально, когда я смотрю на него через их веб-интерфейс. Однако git clone на моей Unix-машине дает мне два сообщения вроде:
error: unable to create symlink ... (File name too long)
и два файла, которые ранее были символическими ссылками, отсутствуют. Я попытался клонировать в /tmp/..., чтобы получить более короткие имена файлов, но получил те же результаты. Это говорит о том, что что-то пошло не так с репозиторием Bitbucket. Я пробовал core.symlinks
и выключал.
Я могу жить без символических ссылок, но я хотел бы иметь рабочий репозиторий. Кто-нибудь знает способ (кроме воссоздания хранилища)?
Ответы
Ответ 1
Как только вы изменили содержимое файла fake-symlink без изменения его режима с символической ссылки на обычный файл и зафиксировали результат, вы сделали blob, который невозможно извлечь в ОС с настоящими символическими ссылками, потому что у вас есть объект, который должен быть символической ссылкой, но его содержимое слишком длинное, чтобы быть именем пути. Веб-интерфейс не делает вам никаких выгод, скрывая эту проблему.
Вам, вероятно, придется выполнить резервное копирование, чтобы зафиксировать его, исправить и повторно передать все после него. git rebase -i
поможет, но это все равно может быть нелегко, особенно если вы внесли больше изменений в файлы, когда они находились в этом фиктивном состоянии symlink-but-not-really-a-symlink.
Предположим, что bad commit abcdef123
, вам нужно сделать это:
git rebase -i 'abcdef123^'
который поместит вас в редактор со списком коммитов. abcdef123
должен находиться в первой строке. В этой строке измените pick
на edit
. Если есть более одного плохого коммита, измените их все на edit
. Сохраните и выйдите из редактора.
Теперь вы вернетесь в момент, когда вы совершили плохой файл. Это ваш шанс изменить историю, приложив все к чему, когда-то пошло не так. Осмотрите фиксацию с помощью
git show
и отмените неудачную часть, восстановив исходный путь symlink в файле и git add
. Или вы действительно можете избавиться от symlink правильно с помощью git rm
, а затем создать новый файл и git add
, что. Если вы выберете первый вариант, имейте в виду, что содержимое символической ссылки - это просто путь. Это не текстовый файл - он не имеет новой строки в конце. Если вы отредактируете его с помощью текстового редактора, который добавит новую строку, у вас будет сломанная символическая ссылка (указывающая на файл с новой строкой в его имени).
После того, как вы выполнили свой git add
, вставьте фиксированную фиксацию в свое место в истории:
git commit --amend
git rebase --continue
Если вы изменили несколько коммитов от pick
до edit
, вам придется повторить эту процедуру для каждого из них. Окончательный git rebase --continue
вернет вас к настоящему.
Если вы участвуете в прошлой фиксации во время rebase, и вы обнаруживаете, что вся фиксация плохая (она не сделала ничего другого, кроме замены символической ссылки на немодифицированный контент файла, на который она указывает), тогда вы можете git rebase --skip
вместо о внесении изменений и продолжении. Если вы заранее знаете, что это произойдет, вы можете просто удалить плохое коммит из списка git rebase -i
вместо изменения pick
на edit
.
Если у вас несколько ветвей, затронутых плохим фиксатором (-ами), вам придется повторить всю процедуру для каждой ветки. Проверьте ветвь, запустите git rebase -i
до завершения (когда git rebase --continue
говорит "Успешно переустановлено" ), затем проверьте следующую ветку и повторите ее.
В будущем, когда вы раскалываете свою разработку между Windows и реальной ОС, работайте в Windows с cygwin. Внутри cygwin символические ссылки являются символическими ссылками, и вы не можете их испортить, как и вы.
Ответ 2
Вот решение, которое не требует от вас возврата и исправления.
В конце концов, это может быть нецелесообразно, если репо является удаленным или общим.
Он использует core.symlinks = false. Вы сказали, что попробовали это, но не сказали, когда.
Вы должны сделать это до проверки, которую по умолчанию делает обычный клон.
Таким образом, вы должны клонировать с опцией -no-checkout.
git clone --no-checkout the-repo tmp-clone-dir
cd tmp-clone-dir
git config core.symlinks false
git checkout
cp the-problem-file the-problem-file.bak # make a backup
git rm the-problem-file
git commit -m 'Removed problem file pretending to be a symlink' the-problem-file
mv the-problem-file.bak the-problem-file # restore the backup; now it will be of type file
git commit -m 'Added back the problem file - now with the correct type' the-problem-file
git push origin master
cd ..
\rm -rf tmp-clone-dir # IMPORTANT
Этот последний шаг важен, потому что вы не хотите больше работать в репо с помощью core.symlinks = false. Он просто просит неприятностей.
Вышеупомянутое предполагает, что вы хотите, чтобы файл был файлом, а не символической ссылкой. Если бы это означало символическую ссылку, то вы остановились бы после первого фиксации, удалили tmp-clone-dir и вернулись к своей обычной проверке репо, чтобы сделать символическую ссылку и зафиксировать ее.
Преимущество этого метода заключается в том, что вы не нарушаете связанных клонов и ветвей, поскольку он сохраняет историю. Недостатком этого является то, что сломанная фиксация все еще существует и вызовет проблемы для всех, если они попытаются использовать эту конкретную ошибку.
Ответ 3
У меня была эта проблема, это разрешило это для меня:
git config core.symlinks false
git rm <problem-file>
git commit <problem-file>
git push
git config core.symlinks true
Ответ 4
Существует также более простой способ, если вы используете битбакет. С тех пор, как битбакет поддерживает онлайн-удаление файлов, вы можете перейти к вашему репо на битбакете, найдите файл, который является проблематичным, нажмите кнопку раскрывающегося списка рядом с кнопкой "Изменить" и "Удалить".
Это приведет к удалению файла со сломанной символической ссылкой и снова будет рабочий каталог. если это возможно, это намного быстрее, чем перезагрузка и удаление вручную.
Ответ 5
У меня была такая же проблема с небольшим количеством файлов. Я решил это, удалив их из репозитория с помощью git remove --cached <file>
который не удаляет файлы в моем источнике (которые больше не являются символическими ссылками). Когда все они удалены, git видит, что они все еще там, поэтому я могу добавить их обратно, используя git add.
и затем передайте их обратно. Теперь git видит их как обычные файлы.