Git:无法创建符号链接(文件名太长)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18411200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 08:56:38  来源:igfitidea点击:

Git: unable to create symlink (File name too long)

gitbitbucketsymlink

提问by Martin Drautzburg

I had pushed a project from Linux to Bitbucket and then cloned it on Windows. Turns out there were two symlinks, which appeared as textfiles on Windows. Since I knew where they should point to, I replaced them by copies of their destination files, committed and pushed.

我将一个项目从 Linux 推送到 Bitbucket,然后在 Windows 上克隆它。结果发现有两个符号链接,它们在 Windows 上显示为文本文件。因为我知道它们应该指向哪里,所以我用目标文件的副本替换了它们,提交和推送。

Now the Bitbucket repository looks okay when I look at it from their web interface. However a git clone on my Unix machine gives me two messages like:

现在,当我从他们的 Web 界面查看 Bitbucket 存储库时,它看起来不错。然而,我的 Unix 机器上的 git clone 给了我两条消息,例如:

error: unable to create symlink ... (File name too long)

and the two files, which were symlinks previously are absent. I tried cloning into /tmp/... to get shorter filenames, but got the same results. That suggests, that something went bad with the Bitbucket repository. I tried core.symlinkson and off.

并且之前作为符号链接的两个文件不存在。我尝试克隆到 /tmp/... 以获得更短的文件名,但得到了相同的结果。这表明 Bitbucket 存储库出了问题。我试了试core.symlinks

I can live without the symlinks, but I'd like to have a working repository. Does anybody know a way (other than recreating the repository)?

我可以没有符号链接,但我想要一个可以工作的存储库。有没有人知道一种方法(除了重新创建存储库)?

采纳答案by Martin Drautzburg

As soon as you changed the content of a fake-symlink-file without also changing its mode from symlink to regular file and committed the result, you made a blob that can't be extracted on an OS with real symlinks, because you have an object that is supposed to be a symlink but its content is too long to be a pathname. The web interface is not doing you any favors by hiding this problem.

一旦您更改了伪符号链接文件的内容,而没有将其模式从符号链接更改为常规文件并提交结果,您就创建了一个无法在具有真实符号链接的操作系统上提取的 blob,因为您有应该是符号链接但其内容太长而不能作为路径名的对象。通过隐藏此问题,Web 界面对您没有任何帮助。

You're probably going to have to back up to that commit, fix it, and re-commit everything after it. git rebase -iwill help, but it still might not be easy, especially if you've made more changes to the files while they were in this bogus symlink-but-not-really-a-symlink state.

您可能将不得不备份到那个提交,修复它,并在它之后重新提交所有内容。git rebase -i会有所帮助,但它仍然可能并不容易,特别是如果您在文件处于这种虚假的符号链接但不是真正的符号链接状态时对其进行了更多更改。

Supposing that the bad commit is abcdef123, you need to do this:

假设错误的提交是abcdef123,你需要这样做:

git rebase -i 'abcdef123^'

which will put you in an editor with a list of commits. abcdef123should be on the first line. On that line, change pickto edit. If there is more than one bad commit, change all of them to edit. Save and exit the editor.

这将使您进入带有提交列表的编辑器。abcdef123应该在第一行。在该行上,更改pickedit。如果有多个错误提交,请将它们全部更改为edit. 保存并退出编辑器。

Now you'll be back in the point in time where you committed the bad file. This is your chance to alter history, putting things right that once went wrong. Inspect the commit with

现在您将回到提交错误文件的时间点。这是你改变历史、纠正曾经出错的事情的机会。检查提交

git show

and undo the bad part by restoring the original symlink pathname into the file and git adding it. Or you could really get rid of the symlink properly with git rm, then create a new file and git addthat. If you choose the first option, be aware that the content of a symlink is just a pathname. It's not a text file - it doesn't have a newline on the end. If you edit it with a text editor that adds a newline, you'll have a broken symlink (pointing to a file with a newline in its name).

并通过将原始符号链接路径名恢复到文件中并对其进行git adding 来撤消坏部分。或者你真的可以用 正确地摆脱符号链接git rm,然后创建一个新文件git add。如果您选择第一个选项,请注意符号链接的内容只是一个路径名。它不是文本文件 - 它的末尾没有换行符。如果使用添加换行符的文本编辑器对其进行编辑,则符号链接将损坏(指向名称中带有换行符的文件)。

After you've done your git add, reinsert the fixed commit into its place in history:

完成后git add,将固定提交重新插入历史记录中的位置:

git commit --amend
git rebase --continue

If you changed multiple commits from pickto edityou'll have to repeat that procedure for each one. The final git rebase --continuewill bring you back to the present.

如果您将多个提交从 更改pickedit,则必须为每个提交重复该过程。决赛git rebase --continue将带你回到现在。

If you are at a past commit during the rebase and you discover that the whole commit is bad (it did nothing else besides replacing a symlink with the unmodified content of the file it points to), then you can git rebase --skipinstead of amending and continuing. If you know ahead of time that this is going to happen, you can just delete the bad commit from the git rebase -ilist instead of changing its pickto edit.

如果您在 rebase 期间处于过去的提交中,并且您发现整个提交很糟糕(除了用它指向的文件的未修改内容替换符号链接之外,它什么也没做),那么您可以git rebase --skip而不是修改并继续。如果您提前知道这将会发生,您可以从git rebase -i列表中删除错误提交而不是将其更改pickedit.

If you have multiple branches affected by the bad commit(s), you will have to repeat the whole procedure for each branch. Check out a branch, run the git rebase -ito completion (which is when git rebase --continuesays "Successfully rebased"), then check out the next branch and do it again.

如果您有多个分支受到错误提交的影响,则必须为每个分支重复整个过程。签出一个分支,运行git rebase -i到完成(当git rebase --continue说“成功重新定位”时),然后签出下一个分支并再次执行。

In the future, when splitting your development work between Windows and a real OS, do your Windows work with cygwin. Inside cygwin, symlinks are symlinks and you can't mess them up like you did.

将来,当在 Windows 和真实操作系统之间拆分开发工作时,请使用 cygwin 进行 Windows 工作。在 cygwin 中,符号链接是符号链接,你不能像以前那样把它们弄乱。

回答by Matthew Hannigan

Here's a solution that doesn't require you to go back and fix commits. After all it may not be feasible if the repo is remote or shared. It uses core.symlinks=false. You said you tried this but did not say when. You must do it before a checkout, which a normal clone does by default. So you must clone with the --no-checkout option.

这是一个不需要您返回并修复提交的解决方案。毕竟,如果 repo 是远程的或共享的,则可能不可行。它使用 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

That last step is important because you don't want to do more work in a repo with core.symlinks=false. It's just asking for trouble.

最后一步很重要,因为您不想在带有 core.symlinks=false 的存储库中做更多工作。这只是自找麻烦。

The above assumes that you want the file to be a file not a symlink. If it was meant to be a symlink then you'd stop after the first commit, remove the tmp-clone-dir and go back to your normal repo checkout to make the symlink and commit it.

以上假设您希望文件是文件而不是符号链接。如果它是一个符号链接,那么你会在第一次提交后停止,删除 tmp-clone-dir 并返回到你的正常 repo checkout 以制作符号链接并提交它。

The benefit in this method is that you don't break any related clones and branches as it preserves history. The downside to this is that the broken commit is still there and will cause problems for anyone if they attempt to use that particular bad commit.

这种方法的好处是您不会破坏任何相关的克隆和分支,因为它保留了历史记录。这样做的缺点是损坏的提交仍然存在,如果他们尝试使用该特定的错误提交,则会给任何人带来问题。

回答by gitaarik

I had this problem, this resolved it for me:

我遇到了这个问题,这为我解决了:

git config core.symlinks false
git rm <problem-file>
git commit <problem-file>
git push
git config core.symlinks true

回答by Jan Ambro?i?

There is also an easier way if you are using bitbucket. Since now bitbucket supports online deleting of the files you can go to your repo on bitbucket, find the file that is problematic, press the dropdown button near "Edit" button and "Delete".

如果您使用的是 bitbucket,还有一种更简单的方法。由于现在 bitbucket 支持在线删除文件,您可以转到 bitbucket 上的存储库,找到有问题的文件,按“编辑”按钮和“删除”附近的下拉按钮。

That will delete the file with broken symlink and you have a working directory again. if this is a possibility it is much faster than rebasing and deleting manually.

这将删除符号链接损坏的文件,您将再次拥有一个工作目录。如果这是可能的,它比手动变基和删除要快得多。

回答by PedroKTFC

I had the same problem with a small number of files. I solved it by removing them from the repository using git remove --cached <file>which doesn't delete the files in my source (which are no longer symlinks). Once all are removed, git sees they're still there so I can add them back using git add .and then commit them back in. Now git sees them as normal files.

我在处理少量文件时遇到了同样的问题。我通过使用它从存储库中删除它们来解决它git remove --cached <file>,它不会删除我的源中的文件(不再是符号链接)。全部删除后,git 看到它们仍然存在,因此我可以将它们添加回使用git add .,然后将它们重新提交。现在 git 将它们视为普通文件。