Mercurial: Commit files with more than 255 characters path length (Windows)?
Asked Answered
S

5

13

I try to commit a folder hierarchy into out Mercurial repository, which contains files, whiches absolute path length exceeds 255 characters (Windows max. path length).

For these files I receive an error message saying

The system cannot find the path specified

We use TortoiseHG and an Eclipse plugin for Mercurial, both don't work.

Has anybody found a solution for this? (I do not want to change the repository's location on my HD)

Steiermark answered 25/5, 2012 at 11:55 Comment(1)
I don't think it will make a difference, but have you tried running hg commit on the command line?Cherice
S
19

There exists an extension which is aimed at solving this exact problem. It is: https://www.mercurial-scm.org/wiki/Win32LongFileNamesExtension

It uses \\?\ style names to transparently handle long files.

I'm the author, let me know if it works for you.

Skulduggery answered 29/5, 2012 at 4:1 Comment(4)
To install (as not very clear): 1) Download .py file from bitbucket.org/remleduff/win32lfn/downloads, 2) link it in mercurial.ini as indicated here: mercurial.selenic.com/wiki/Win32LongFileNamesExtension and you are OK!Estival
Exactly. We've done this in our whole company. The above link is dead. Please use this one: bitbucket.org/remleduff/win32lfnSteiermark
Thanks @Windwalker, I just updated the URL in the answer.Skulduggery
Make sure TortoiseHG/Mercurial is up to date before using this. I tried this script with an older version (TortoiseHG 3.7.3) and it wouldn't work until I updated.Mulford
M
7

I've just installed Aaron Cohen' extension, as he suggested. And it perfectly works with my TortoiseHG 2.6.1 ! Thanks, Aaron!

Though, I'd like to add a detailed guide here, because I cannot find one...

(At least here's what I did on my Win7 x64 - I'm not sure this is the shortest way possible)

1. Download Mercurial-py

  • Note the Python version required
  • I've downloaded "Mercurial-2.4.2 (64-bit py2.7)"

2. Download Python

  • Make sure you're downloading compatible version.
  • I used "Windows X86-64 MSI Installer (2.7.3)" link

3. Install Python

  • I've installed it to "D:\Python27"

4. Download pywin32

  • It's required by the Win32LongFileNamesExtension.
  • Note the Python version number in pywin32's filename.
  • I used "pywin32-218.win32-py2.7.exe"

5. Install pywin32

  • Make sure installer detected correct Python installation
  • In my case, it's installed in "d:\Python27\Lib\site-packages\pywin32_system32\"

6. Install Mercurial

  • Make sure installer detected correct Python installation
  • In my case, it's installed in "d:\Python27\Lib\site-packages\mercurial\"

7. Set PYTHONPATH enviroment variable

setx PYTHONPATH d:\Python27\Lib\site-packages\win32lfn\src;d:\Python27\Lib\site-packages\mercurial\
  • Use this cli command, or do the same using some other method
  • Of course, you should adapt paths to your needs
  • Restart your cli after this, to make sure env. variable is now properly set

8. Download win32lfn

9. Do interanal win32lfn tests

cd /D D:\Python27
python d:\Python27\Lib\site-packages\win32lfn\tests\testwin32lfn.py

10. Create a backup of your repository.

  • For me, everything went just fune, but you never know....

11. Add win32lfn to hgrc

[extensions]
win32lfn = d:\Python27\Lib\site-packages\win32lfn\src\win32lfn.py
  • you can find "hgrc" in your ".hg" folder, inside your repository

12. Test it!

Mra answered 12/1, 2013 at 4:14 Comment(3)
Just a note, but I just made a commit removing the need for pywin32.Skulduggery
This is so long! I just placed the py file in my tortoisehg directory, and added the extension to mercurial.ini - worked fine.Dribble
are you kidding? download .py file, link it in mercurial.ini as in the 11th step and you are done!Estival
S
2

See https://www.mercurial-scm.org/wiki/Win32LongFileNamesExtension (Aaron pointed to it via the mercurial-devel mailing list).

Another workaround without changing the path to the repo could be to create a second path to it by means of directory junction points. It may work because the reparsing is done at a very low level by the file system driver (or rather some installed filter), so the full (Unicode) path is known by that time and the expansion to beyond 260 characters should work fine. Give it a try. You can use the tool mklink on Windows Vista or 7 and junction.exe from Sysinternals on Windows 2000 or later. For mklink make sure to create a junction point. I'm not sure the reparsing mechanism works the same for directory symlinks (although I faintly remember that it should).


If you don't have a Unicode version of the program available, the limit is 260 characters (including drive letter part). There is nothing to get around it.

However, all ANSI functions are implemented by means of their Unicode counterpart and therefore you may get lucky by providing the full path prepended with \\?\. This may work, but likely won't because the program itself didn't consider anything beyond MAX_PATH (= 260). Ask the author to compile a Unicode version and use the prefix I mentioned. This will fix the issue.

This is a limit of the Win32 subsystem. The absolute path length limit is approximately 32,767 characters. Approximately because the object manager of Windows may expand it (symlinks in the object namespace and the likes).

Sr answered 25/5, 2012 at 13:19 Comment(4)
While your answer is technically correct, I'm afraid it isn't useful — Mercurial is a Python program and cannot just be recompiled in a "Unicode" version. The problem is a known problem with Mercurial and it has been discussed on the mailinglist. There is no good workaround right now.Backwoodsman
Actually Python can be, as far as I can tell. But that would still require some care on part of the Python program to make use of the `\\?` prefix.Sr
@MartinGeisler: I added a potential workaround that popped to mind. But all in all I think it is better to point out if something does not work than leave the OP in the dark about the limitations and where they are and why.Sr
Your answer is informative and correct — it's just not a practical solution since Mercurial doesn't use the API for long file names (up to 32K characters, I believe) on NTFS. It was discussed in April and it was explained that Windows Explorer cant handle files written using this API. The consensus was that Mercurial can switch when Windows itself has switched. (Please join the discussion on the mailinglist if you know more about this, I'm just a Linux user who observed the discussion.)Backwoodsman
S
2

The quick and dirty solution is to map a network drive.

For the path c:\some long path\project folder

Map \\localhost\c$\some long path\ to drive Z:\

cd z:\project folder
hg push

We are using this successfully as an interim solution, before migrating to shorter paths.

The mercurial plugins above look good but unfortunately there are numerous non-mercurial bugs related to path greater than 255 characters. For example the VS2010 failure at exactly 259 characters is a real corker!

http://support.microsoft.com/kb/2516078

Subtlety answered 14/1, 2013 at 11:14 Comment(0)
A
0

Windows 10 system running the mercurial 4.4.1 client

Aaron Cohen extension will work I did need make a small one small tweak

based on a comment from mhaecki on this thread: https://bitbucket.org/remleduff/win32lfn/issues/13/not-compatible-with-version-431

in the win32lfn.py file I changed:

from mercurial import util, osutil,cmdutil
from mercurial.i18n import _

to:

from mercurial import util, cmdutil
from mercurial.cext import osutil
from mercurial.i18n import _
Anonym answered 4/1, 2018 at 19:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.