JGit Clone File Name too long

使用 JGit Clone 時出現 java.io.IOException: File name too long 的應對方法

在使用 JGit 的 CloneCommand 時出現 java.io.IOException: File name too long 的 Exception

原本懷疑是 Git Clone 的問題,但是使用原生 Git 來 Clone 時卻能完整抓出所有檔案...

接下來有在不同 OS 下測試,結果也不一樣, Windows 10 使用 JGit 是正常的,但是 CentOS 卻有問題,

所以我將 OS 底下能夠接受檔名的長度拿來比較

(來源圖片: 維基百科 https://en.wikipedia.org/wiki/Filename)

可以看到 Windows 10 是255字元, Linux 是 256 字元,所以就往 JGit 底層去追了。

發現下面的程式碼

File tmpFile = File.createTempFile("._" + f.getName(), null, parentDir);​

代表 Clone 時會先 Temp 一份出來,並且會增加一些亂數導致 File Name 長度變長 !

後來發現有人發了這篇文章,所以正常來說只要更新到 2017-05-09 以後的版本就可以解決這個問題了 !
https://bugs.eclipse.org/bugs/show_bug.cgi?id=508823

修改的部分如下,就可以發現可以排除檔名太長的問題

String name = f.getName();
if (name.length() > 200) {
	name = name.substring(0, 200);
}
File tmpFile = File.createTempFile("._" + name, null, parentDir);

但是更新後發現在 CentOS 底下還是有問題,但是 Windows 10 卻是正常的,就繼續往下追

最後發現是中文編碼的問題,中文在 UTF 8 (CentOS)可能為 1~3 個字元,UTF 16 (Windows10)為固定 2 個字元 

所以相同的文字在不同編碼佔了不同的字元

所以就知道為什麼在 Windows10 沒問題,但是 CentOS 確有問題了,但是有提到說新版的 JGit 會去判斷 name.length > 200 這段

但是為什麼不行呢 ? 因為中文字大概長度不到 100 就超過限制的 256 字元了,所以永遠進入不了那個判斷式 !

這邊還有人會問說那原生 Git 為什麼可以 Clone 呢,因為 JGit 還有做 Temp 的手腳,所以長度會暴增... 

這邊提供幾個解決辦法
1. 避免放入太長中文字的檔名
2. 改寫 JGit 的方法

 

參考 :

https://en.wikipedia.org/wiki/Filename
https://bugs.eclipse.org/bugs/show_bug.cgi?id=508823
https://ethproductions.github.io/bytes/