25

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

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

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

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

我可以在没有符号链接的情况下生活,但我希望有一个工作存储库。有没有人知道一种方法(除了重新创建存储库)?

4

6 回答 6

29

这是一个不需要您返回并修复提交的解决方案。毕竟,如果 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

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

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

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

于 2014-10-25T02:01:19.153 回答
15

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

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

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

git rebase -i 'abcdef123^'

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

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

git show

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

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

git commit --amend
git rebase --continue

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

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

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

将来,当您在 Windows 和真实操作系统之间拆分开发工作时,您的 Windows 是否与 cygwin 一起工作。在 cygwin 内部,符号链接是符号链接,你不能像以前那样把它们弄乱。

于 2013-08-24T14:48:38.117 回答
15

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

git config core.symlinks false
git rm <problem-file>
git commit <problem-file>
git push
git config core.symlinks true
于 2015-07-10T13:21:54.800 回答
2

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

于 2019-05-15T21:48:04.083 回答
0

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

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

于 2015-07-23T08:53:15.443 回答
0

git config --global core.longpaths true 放这个再试一次。它会起作用的。

于 2022-01-06T09:49:10.363 回答