简体   繁体   English

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

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

I had pushed a project from Linux to Bitbucket and then cloned it on Windows.我已经将一个项目从 Linux 推送到 Bitbucket,然后将其克隆到 Windows 上。 Turns out there were two symlinks, which appeared as textfiles on Windows.原来有两个符号链接,在 Windows 上显示为文本文件。 Since I knew where they should point to, I replaced them by copies of their destination files, committed and pushed.因为我知道它们应该指向哪里,所以我用它们的目标文件副本替换它们,提交并推送。

Now the Bitbucket repository looks okay when I look at it from their web interface.现在,当我从他们的 Web 界面查看 Bitbucket 存储库时,它看起来还不错。 However a git clone on my Unix machine gives me two messages like:然而,我的 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.我尝试克隆到 /tmp/... 以获得更短的文件名,但得到了相同的结果。 That suggests, that something went bad with the Bitbucket repository.这表明,Bitbucket 存储库出了点问题。 I tried core.symlinks on and off.我尝试打开和关闭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)?有没有人知道一种方法(除了重新创建存储库)?

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.毕竟,如果 repo 是远程的或共享的,这可能是不可行的。 It uses core.symlinks=false.它使用 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.因此,您必须使用 --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.最后一步很重要,因为您不想在 core.symlinks=false 的 repo 中做更多的工作。 It's just asking for trouble.这只是自找麻烦。

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.这样做的缺点是损坏的提交仍然存在,如果他们尝试使用那个特定的错误提交,将会给任何人带来问题。

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

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.只要您更改了假符号链接文件的内容而不将其模式从符号链接更改为常规文件并提交了结果,您就制作了一个无法在具有真实符号链接的操作系统上提取的 blob,因为您有一个应该是符号链接但其内容太长而不能成为路径名的对象。 The web interface is not doing you any favors by hiding this problem.通过隐藏此问题,Web 界面对您没有任何帮助。

You're probably going to have to back up to that commit, fix it, and re-commit everything after it.您可能必须备份到那个提交,修复它,然后重新提交它之后的所有内容。 git rebase -i will 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.这将使您进入带有提交列表的编辑器。 abcdef123 should be on the first line. abcdef123应该在第一行。 On that line, change pick to edit .在该行上,将pick更改为edit If there is more than one bad commit, change all of them to edit .如果有多个错误提交,请将它们全部更改为edit Save and exit the editor.保存并退出编辑器。

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 add ing it.并通过将原始符号链接路径名恢复到文件中并git add来撤消坏部分。 Or you could really get rid of the symlink properly with git rm , then create a new file and git add that.或者你真的可以用git rm正确地摆脱符号链接,然后创建一个新文件并git add 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).如果您使用添加换行符的文本编辑器对其进行编辑,则会有一个损坏的符号链接(指向名称中带有换行符的文件)。

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 pick to edit you'll have to repeat that procedure for each one.如果您将多个提交从pick更改为edit ,则必须对每个提交重复该过程。 The final git rebase --continue will bring you back to the present.最后的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 --skip instead of amending and continuing.如果您在变基期间处于过去的提交中并且您发现整个提交是错误的(除了用它指向的文件的未修改内容替换符号链接之外,它什么也没做),那么您可以git rebase --skip而不是修改和继续。 If you know ahead of time that this is going to happen, you can just delete the bad commit from the git rebase -i list instead of changing its pick to edit .如果您提前知道这将发生,您可以从git rebase -i列表中删除错误提交,而不是将其pick更改为edit

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 -i to completion (which is when git rebase --continue says "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.将来,当您在 Windows 和真实操作系统之间拆分开发工作时,您的 Windows 是否与 cygwin 一起工作。 Inside cygwin, symlinks are symlinks and you can't mess them up like you did.在 cygwin 内部,符号链接是符号链接,你不能像以前那样把它们弄乱。

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).我通过使用git remove --cached <file>从存储库中删除它们来解决它,它不会删除我的源中的文件(不再是符号链接)。 Once all are removed, git sees they're still there so I can add them back using git add .删除所有内容后,git 会看到它们仍然存在,因此我可以使用git add . and then commit them back in. Now git sees them as normal files.然后将它们重新提交。现在 git 将它们视为普通文件。

There is also an easier way if you are using bitbucket.如果您使用的是 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上的repo,找到有问题的文件,按“编辑”按钮和“删除”附近的下拉按钮。

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.如果这是一种可能性,它比手动重新定位和删除要快得多。

git config --global core.longpaths true git config --global core.longpaths true

Put this one and try again.放这个,然后再试一次。 It will work.它会起作用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM