Як клонувати Linux на Windows

💡 Усі статті, обговорення, новини про DevOps — в одному місці. Приєднуйтесь до DevOps спільноти!

Я не знаю, як я можу знаходити собі такі пригоди, але інколи зламаний софт сам мене знаходить, навіть коли я не шукаю пригод активно. Сьогоднішня пригода про легасі Windows та клонування Linux.

Ніщо не вказувало на проблеми, я спокійнісінько розбирався із програмою автоматичного символьного перезапису, намагаючись побудувати свій аналог. В цілому нормальний задротський відпочинок. Реверсінг поведінки погано документованих систем це кумедно. Навіть коли це прості речі типу функції друкування prn. Після того як я був задоволений своїми знахідками, я зміг зробити тест для поведінки цієї функції, і записав його у файл prn.ap.

Потім як порядошна людина я вирішив, що це доволі гарна праця, тому я вирішив її зберегти. Натикавщи що мені треба в Zed і радісно натиснув кнопку Сommit. Але Zed вирішив що щось не так, написав мені помилку, і зняв галочку із файлу. Тобто він не залишився в індексі. Як нормальний програміст, я вирішив що треба спробувати знову, і звісно із другого разу все запрацює. Звісно нічого не запрацювало. Це мене дуже спантеличило, тому я пішов в термінал щоб побачити що насправді коїться, бо Zed не дуже хоче показувати нормальні повідомлення про помилки Git. Ось що мені показав термінал.

git add .\samples\prn.ap -f
error: open("samples/prn.ap"): No such file or directory
error: unable to index file 'samples/prn.ap'
fatal: adding files failed

Окей думаю, щось мабуть таки не те, може файл видалився. Пішов в Zed — там файл інсує, пару раз зберіг, знову спробував додати. Звісно із тим самим результатом. Можна бачити, як я не хочу приймати реальність і намагаюся торгуватися із нею, вважаючи що щось само виправиться. Потім я перевірив таки чи файл є, more .\samples\prn.ap. Таки є, і змісти не пустий. Тоді я вирішив що час для чарівної ШІ-палочки. ШІ-шка мені сказала що, мабуть prn is a reserved Windows device name.

Точно, є така проблема, але ж у мене prn.ap, яка зарезервована назва. Ну коротше я знову поторгувався із всесвітом, і поліз шукати похідний код для Git for Windows. Спеціальні файли для Windows записані в тестах github.com/...​/t0060-path-utils.sh#L591. Спочатку мене спантеличило, чому prn.abc в тесті явно перевіряються, але якщо піти в комміт який додав цей тест — github.com/...​e22f1f04a1a247b5a7538b8af, то стає більш менш зрозуміло що проблема задокументована у Microsoft. Щоб ви не шукали що саме важливе, ось цитата із сайту.

Do not use the following reserved names for the name of a file:
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, COM¹, COM², COM³, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, LPT¹, LPT², and LPT³. 
Also avoid these names followed immediately by an extension; for example, NUL.txt and NUL.tar.gz are both equivalent to NUL. 
For more information, see Namespaces (https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#win32-file-namespaces).

Окей, із цього зрозуміло що мейнтейнери Git for Windows мають консервативну позицію і перестрахувалися спираючись на слово avoid.

Пошуки правди

В цей час я зрозумів що я на жаль вїхав в проблему Git for Windows. Це звісно мені не сподобалося. Я вирішив як мінімум зарепортити проблему. Ця проблема задокументована тут — github.com/...​r-windows/git/issues/4005. Як можна бачити що 4 роки минуло як люди побачили її та вона почала когось турбувати. Я радісно написав, давайте все нафіг міняти на Windows 11 все працює. Не робіть так!

Після того як адреналіновий раш закінчився, я уважно перечитав проблему і побачив що вже раніше люди писали про Windows 11, і майнтейнер прагматично відповів що він підтримує мільйони людей і не може просто так щось поміняти. Це звісно правильна позиція, тому я спробував якось завоювати довіру людини і поспілкуватися про альтернативні можливості для фіксу. Нажаль, мені здалося що поки контакту не виходить, незважаючи, що наче накопичується більше свідоцтв що це працює не лише у мене на машині.

Типова ситуація у проектах із відкритим кодом, коли незламний рух стикається із нерухомим мейнтейнером. Я думаю, ви бачите ролі в цьому спектаклі доволі чітко. Що в такій ситуації можна зробити. Я вирішив, що можна піти до знайомих, які працюють в Мікрософт і попитати у них, що вони думають, і чи можна якось добратися до кішок команди Windows і щоб якщо не мені відповіли, але хоча б хтось краще задокументував коли стало краще жити, із якої версії вінди. Другий шлях це використати свій статус як MVP і спробувати пошерстити Мікрософт, або таких саме MVP що може вони хоча б порадою допоможуть.

Це типові адміністративні речі які часто не працюють, але вони інколи дуже гарно працюють, тому їх завжди треба робити. Матриця допомагає тим, хто рухається вперед. Поки ці кволі процеси йдуть, мені залишається лише один варіант. Спробувати подивитися як зробити форк, і пофіксати проблему.

Як зробити свій Git для Windows

Проект сам по собі дуже гарно готовий для контрібьюту. Якщо ви зайдете на головну сторінку gitforwindows.org то ви побачити там розділ Git for Windows SDK : Contributing Code, просто завантажте звідти Git for Windows SDK. Коли буде потрібно вибирати вибирайте 64-бітний варіант. Чому? Ну, мабуть тому що ми в 64-бітному світі живемо. Фактично СДК це кастомізована інсталяція MINGW де додани деякі скріпти щоб зручно було білдити проект. Я встановив SDK в папку c:\git-sdk-64. Це далі взагалі не принципово. Після встановлення запускайте SDK.

При першому старті, SDK ініціалізується автоматично, тому вам потрібен буде стабільний інтернет. Принаймні краще його б мати, бо я не знаю як система себе поведе, якщо щось там не доставиться, і наскільки проблемно вам буде займатися відновленням СДК до робочого стану. Після того як ініціалізація завершилася, вам пропонується почитати справку за допомогою команди sdk help. Рекомендую почитати, там не дуже багато інформації, плюс явно більшості хакерів не потрібно буде виконувати всі ці команди. Ось що написало мені

The 'sdk' shell function helps you to get up and running
with the Git for Windows SDK. The available subcommands are:

create-desktop-icon: install a desktop icon that starts the Git for
    Windows SDK Bash.

cd <project>: initialize/update a worktree and cd into it. Known projects:
        git git-extra msys2-runtime installer build-extra
        MINGW-packages MSYS2-packages mingw-w64-busybox mingw-w64-curl
        mingw-w64-cv2pdb mingw-w64-git mingw-w64-git-credential-manager
        mingw-w64-git-lfs mingw-w64-git-sizer mingw-w64-wintoast
        bash curl gawk gnupg heimdal mintty nodejs openssh openssl
        perl perl-HTML-Parser perl-Locale-Gettext perl-Net-SSLeay
        perl-TermReadKey perl-XML-Parser perl-YAML-Syck subversion tig

init <project>: initialize and/or update a worktree. Known projects
    are the same as for the 'cd' command.

build <project>: builds one of the following:
        git-and-installer git git-extra msys2-runtime installer
        mingw-w64-busybox mingw-w64-curl mingw-w64-cv2pdb mingw-w64-git
        mingw-w64-git-credential-manager mingw-w64-git-lfs
        mingw-w64-git-sizer mingw-w64-wintoast bash curl gawk gnupg
        heimdal mintty nodejs openssh openssl perl perl-HTML-Parser
        perl-Locale-Gettext perl-Net-SSLeay perl-TermReadKey
        perl-XML-Parser perl-YAML-Syck subversion tig

edit <file>: edit a well-known file. Well-known files are:
        git-sdk.sh sdk.completion ReleaseNotes.md install.iss

reload: reload the 'sdk' function.

`

Я персонально використовував лише наступні команди git build git-and-installer, git init git та git build git. Друга команда робиться один раз при старті хакінку. Третя команда це більше про більш швидку перевірку компіляції, без збірки інсталятора та тестів.

Я виконав git init git, і тепер все готово для хакінгу. Я редагував файли відкривши їх через Explorer в Notepad++, ви можете звісно робити як вам заманеться. Це не принципово, бо редагувати ви будете в одній програмі, а компілювати через Git for Windows SDK. Як я описав в іщью, я вирішив що бажана поведінка повинна виконуватися лише на Windows 11, і це буде доволі безпечно. Тому треба додати функцію яка перевіряє, чи я на Windows 11 і використати її в функції яка перевіряє чи файл має назву яку можна використовувати на Windows.

Швидкий пошук по слову AUX показав мені що функція де я хочу зробити зміну називається is_valid_win32_path у файлі compat/mingw.c. Це було доволі не очевидно, але SDK клонує ісходники в C:\git-sdk-64\usr\src\git. Тому я відкрив на редагування файл C:\git-sdk-64\usr\src\git\compat\mingw.c. В принципі поміняти функцію is_valid_win32_path було дуже просто, але ось знайти механізм знайти версію Windows 11 це вже було складно. Стандартні методи типу GetVersion/GetVersionEx будуть давати лише версію Windows 10, і то якщо я маніфест додам до git.exe.

Це насправді цікаво проблема, бо і розробників Windows я розумію, але і мені щось робити треба. Вирішилося хаком, який порекомендував спочатку Bing а потім людина із Rust чатику. Знайти функцію RtlGetNtVersionNumbers із ntdll.dll, викликати її та подивитися на числа які вона повертає. Як на мене, це не дуже правильне рішення, тому якщо ви знаєте якесь інше, яке би працювало в контексті короткоживучих CLI програм як git.exe, то будь ласка залиште коментарі. Весь поточний патч можна подивитися в коментарі до проблеми github.com/...​5#issuecomment-5760570321

Давайте збирати. sdk build git пішов бурчати, і видав

    CARGO target/x86_64-pc-windows-gnu/release/libgitcore.a
error[E0463]: can't find crate for `std`
  |
  = note: the `x86_64-pc-windows-gnu` target may not be installed
  = help: consider downloading the target with `rustup target add x86_64-pc-windows-gnu`

For more information about this error, try `rustc --explain E0463`.

Дякую панове, я пішов ставити rustup target add x86_64-pc-windows-gnu. Після цього в мене ще було кілька приколів із лінтером, так, у цього проекта кльовий автоматичний лінтер який є частина білда. Панове із С також живуть в сучасному світі. Тому не дивіться на людей зверху лише через мову.

Після того як sdk build git сказав що я красавчик, можна будувати інсталятор. Звісно шлях відкритого коду, навіть такий простий, як із Git for Windows не буває простим. git build git-and-installer починає будувати шарманку, і потім каже

:: Synchronizing package databases...
 git-for-windows-aarch64                                                                  7.1 KiB  31.7 KiB/s 00:00 [####################################################################] 100%
 clangarm64                                                                             558.6 KiB  1181 KiB/s 00:00 [####################################################################] 100%
 git-for-windows-x86_64                                                                  18.8 KiB  32.8 KiB/s 00:01 [####################################################################] 100%
 git-for-windows-mingw32                                                                  8.7 KiB  15.3 KiB/s 00:01 [####################################################################] 100%
 mingw32                                                                                 39.7 KiB  55.8 KiB/s 00:01 [####################################################################] 100%
 mingw64                                                                                407.0 KiB   262 KiB/s 00:02 [####################################################################] 100%
 ucrt64                                                                                 576.3 KiB   137 KiB/s 00:04 [####################################################################] 100%
 clang64                                                                                563.9 KiB   147 KiB/s 00:04 [####################################################################] 100%
 msys                                                                                   481.6 KiB   150 KiB/s 00:03 [####################################################################] 100%
:: Starting core system upgrade...
 there is nothing to do
:: Starting full system upgrade...
error: failed to prepare transaction (package architecture is not valid)
:: package git-extra-1.1.696.db26e322c-1-aarch64 does not have a valid architecture

Це звісно дуже погано, бо мені довелося розбиратися де ця проблема, і шукати де реалізована команда sdk в bash. За цю команду відповідає файл C:\git-sdk-64\etc\profile.d\git-sdk.sh. Якщо перейдете на рядок 355 то побачите щось накшталт такого

git-and-installer)
    sdk build git &&
    echo "============== Running make strip install ==================" && make -C "$src_dir" strip install &&
    #echo "============== Updating MINGW installation ==============" && pacman -Syyu git-extra &&
    sdk init build-extra &&
    "$src_dir"/installer/release.sh "${3:-0-test}"
    ;;

Гра із echo це моя відладка процесу, закоментований рядок це «фікс», в цілому він не зовсім чесний, бо він означєа що я не оновляю залежності як належить, але для локального дев-лупу я не думаю що це принципово. Якщо вам цікаво, звідки ця проблема виникла, то в C:\git-sdk-64\etc\pacman.conf додан розділ

[git-for-windows-aarch64]
Server = https://raw.githubusercontent.com/git-for-windows/pacman-repo/refs/heads/aarch64

який скоріш за все означає, що білд будується на Windows for ARM64. Це в цілому логічно, бо потрібно підтримувати і цю платформу. Альтернативний фікс для людей на x86_64 це закоментувати цей блок, для локальної праці, і не чіпати git-sdk.sh.

Після цього все збудувалося, і процес написав, де він зберіг новий інсталятор. Запускаємо, встановлюємо, і можемо зклонувати Linux на Windows.

Можливо вам вдасться похачити щось більше, і ви якось зробити контрібьют до Лінукса без WSL! Було би дуже кльово.

👍ПодобаєтьсяСподобалось6
До обраногоВ обраному2
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

WSL2 як варіант. Не 100% вирішення всіх проблем, однак все ж краще ніж битися головою об стінку.

P.S: лінь шукати, вже хтось з динозаврів пропонував чарівне «вінда маздай»? ;-)

Та звісно. Нейметься людям. Мабуть думають що я Лінукс не вмію користуватися. Більшість навіть не ідеологічно заряджені на вільний софт

Тут швидше потрібно не латати Гіт, а запропонувати інше концептуальне рішення.

бо крім гіта — та ж сама середовище розробки має вміти читати, зберігати й навіть видаляти файли — той самий aux.c

Ну в мене голова не настільки велика. Примус підлатаю, а нову маркетинг нової системи контроля версій я не потягну. Це складно в головою треба думати

Ну клонь проект в Ubuntu під WSL2 — наче сучасні IDE під Вінду вміють з цими томами працювати — не ламай собі голову

Якщо уважно читали то я взагалі міг просто файл перейменувати і норм. Що я і зробив. Але! Нащо мені ВСЛ якщо я можу спробувати виправити проблему софту. Виправити для всіх не вийшло, але якісь такі покращення вийшло зробити. Так потроху і прийдемо і FSF-соціалізм

На жаль, це не вирішує проблему. Ти перейменовуєш файли, а розробнику потрібен source code.

В своєму проекті я готовий білд виправити :) в цілому якщо бачу простий баг не можу пройти мимо.

на жаль, це не баг. це обмеження

а баг у source code — який нібито кроссплатформовий

У мене немає претензій до Гіт. Він це нормально обробляє, а ось Git for Windows що є MSYS2 fork Git + модифікації має зайві обмеження на мою думку, які я інтерпретую як баг. Мейнтейнер звісно не згоден, але це життя

Ну ви ж розумна людина Володимир :) із цього стаття не родиться :)))

я спеціально все перевіряв ще раз — і навіть вийшло створити папку з ім’ям NUL і файл з ім’ям nul — причому без хаків. За великим рахунком — проблема в існуючому софті — і те, що він також робить попередню перевірку імен файлів, замість методу — «проби і помилки».

У новій Windows 11 все працює і захардшкірені перевірки імен файлів — це очевидний баг.

Попередні версії Віндовс якщо мають підтримку — то на залишковому принципі.

у тому ж Linux можна додати пробіл у кінці імені файлу — і тут 99,99 % усіх і всього не можуть адекватно працювати з таким файлом

99% усіх і всього віндоуз софта неадекватно працює з лінукс файлами?

Навіщо вам Windows? Для початку розберіться з Linux.

Для роботи? У кожного свої уподобання, хіба всі повиннні використовувати лише одну правильну ОС?

Здається, це ті «червоноглазіки» роблять виключно для себе.
На жаль, тут немає правильної ОС.
Я ось від SBT відмовився — бо він має плагіни без підтримки під Windows (спеціально не стежив, можливо, вже полагодили), хоча нібито JVM (Scala) має бути крос-платформною... але, на жаль, розробники спочатку пишуть під Linux і роками нехтують цими моментами... Навіщо в плагіни юзают консольні команди?
... червонооки скрізь їх сунуть, куди не слід!!??? особливо утиліти, які мають бути кросплатформними!!!

з лінукс все окей, тому повернемося до 99% — шо там на віндоуз кнопка Старт чи Глобус не може адекватно працювати з файлами?

писали нижче про UNC — мало програмного забезпечення вміє коректно працювати з цим.

Цей хак — спричиняє біль і страждання.- файл із цікавою назвою стає неможливо видалити стантарними методоми...

тобто у віндоуз «біль і страждання» з файлом який закінчується звичайним пробілом (цілком стандартний символ), а все одно провина на лінуксі що у віндовсі щось не робить, — я правильно зрозумів?

бо не юзаю кнопку Старт та Глобус?

Якщо ви хочете шукати винувату ОС ви звісно знайдете. Я ж не кажу шо для того щоб на Генту працював дотнет треба писати портаж свій. Чи Ніксос все ще погано документовані і всі рекомендують відео подивитися або почитати доки по Ніксу який доволі інша магія і треба вгадувати що і як в ОС інше. Але ж це ще заважає іншим людям користуватися цими ОС. Чому так цікаво бути дрібʼязковою людиною і жирно накидувати

хочете шукати винувату ОС ви звісно знайдете

навіщо щось шукати — трохи запитати деталі, і можна порівнювати

щоб на Генту працював дотнет треба писати портаж свій. Чи Ніксос все ще погано документовані і всі рекомендують відео подивитися або почитати доки по Ніксу

Дистрибутивів лінукса дофіга і трохи більше, у цьому є свої і плюси і мінуси (і плюсів значно більше у наявності різноманіття).

Відносно не мейнстрим дистроc — можна знайти дистрибутив майже на любий смак, і що важливіше, під необхідні задачі які потрібно вирішувати. В цілому, так, оптимальних дистро чи ОС на всі випадки життя — немає.

Дотнет скіпну, бо ніколи не юзав, тому і коментувати нема що відносно того продукта.

Звісно у Лінукс широкий вибір дістрібутивів. Я просто бачу Вінду як ще набір декількох дістрібутивів які я можу користатися (WSL, msys2, win32, Cygwin). Незалежно від того на якій ОС я працюю я намагаюся покращувати ситуацію де я працюю. Чи це мова програмування, чи ліба, чи документація. Весь софт так то поламаний і весь в величезних дирах і проблемах. Вам не муляє одне, мені інше. Для мене головне мати можливість покращити статус кво самостійно. В принципі про це і стаття. Софт можна чинити, і інколи (не буду казати що це завжди) це просто.

бачу Вінду як ще набір декількох дістрібутивів які я можу користатися (WSL, msys2, win32, Cygwin)

я би не назвав msys win32 чи cygwin дистрибутивами ОС, і портувати під них доволі часто не просто

відносно віртуалізації рівня VM і софта в них, то інший підхід, та й там бувають обмеження (що віндоус у віртуалці на лінуксі, що лінукс у віртуалці на віндовс, що навіть умовно лінукс в лінуксі аля debian в chromeos чи в android)

Проблема абсолютно ідентична, коли пишеш під Windows, а на Linux щось пішло не так!

Воркараунд в один бік — це кастильне програмування, та не варто уваги....

Я не зрозумів про що ти, але так — треба фіксати. Це не діло

Набір зарезервованих команд (імен) у Linux відрізняється від набору в Windows — і це неможливо виправити!

Це варто підтримувати, якщо пишеш кросплатформовий код.

О! Мсье знает толк в извращениях! ©

Так, можете почитати мої інші статті, зможете оцінити ступінь гурманства.

А чому не спробувати sapling-scm.com наприклад, чи щось ще з десятка нових альтернатив які навайбкодили за останній рік?

Я б почекав на результати спроби пана перевести на «десяток нових альтернатив» розробку мільйонів проєктів, які зараз на Git.
А ви той Sapling спробували, він дійсно вільно дає створити всякі aux.c навіть на системі, де це заборонено в звичайному API?

Я б почекав на результати спроби пана перевести на «десяток нових альтернатив» розробку мільйонів проєктів, які зараз на Git.

А де тут мова про мільйони проектів? Допис наче про проблему конкретного користувача. Проблеми великих проектів точно вирішені внутрішніми силами проектів і компаній, які їх розробляють.

Допис наче про проблему конкретного користувача.

Про це я теж спитав. Є дані по тому ж Sapling для Linux під Windows?

Проблеми великих проектів точно вирішені внутрішніми силами проектів і компаній, які їх розробляють.

Ті мільйони, що я згадав, вони на 99.9% не великі.

Насправді, може бути 100500 причин, чому не використовуються інші SCM: починаючи з проблем інтеграції з IDE. Git підтримують геть усі. Шукати, перевіряти плагін під якийсь там VSCode чи CLion, а то і вибирати з декількох, міняти звички під нього... я думаю, простіше було дійсно видалити одну застарілу перевірку.

я скоріш попробую якийсь Fossil чи Radicle. JJ мені не зайшов бо я не люблю локальний флоу із великою пачкою змін.

Fossil принципово не має сумісности з Git.

якщо ти про те щоб щось інше взяти щоб склонувати, ну я в цілому навіть не думав про це, це для мене якийсь окремий проект був би, розібратися із усим цим. А тут мене трішки мейнтейнер роздраконив твердженням що не треба для Windows 11 нічого робити, довелося перевірити чи дійсно це так складно. виявилося що таки ні

Працювати з файлами з «зарезервованими» іменами нема проблеми через UNC, там розбір на старі імена не вмикається. Але це складніше. UNC вимагає подавати завжди повний шлях, і якщо код на це не налаштований, то буде дорожче, а Git під Windows і так повільний через повільність NTFS.
Але є 100500 програм під Windows, які не страждають тут проблемами — вони або завжди використовують UNC, або роблять це у сумнівних випадках. Думаю, Zed і та неназвана тулза, що ви використали для перевірки існування файла, це роблять.

Якщо ви б замість простого видалення перевірки зробили, що у випадку підозрілого компоненту в імені доступ перекладається на UNC (наприклад, замість C:\foo\aux.c чи навіть C:/foo/aux.c використовувалось би \\?\C:\foo\aux.c), то це працювало би для всіх версій починаючи десь з Windows 2000 (і його можна було б запропонувати в стоковий Git), а не було б локальним персональним хаком.

Що під Windows 11 нарешті видаляють цю тупу легасі — добра новина, дякую. Спостерігатиму.

Git for Windows скоро буде підтримуватися лише для Windows 10 і вище через те що вони з мігрували на uCRT64, ну і в цілому я міг перевірити лише Він11 а робити підстраховки для ОС якої у мене немає це трішки лячно. Якщо комусь хочеться можуть зробити. Сам процес збірки доволі тривіальний.

Навіть Раст як виявилося в переписці із мейнтенером не треба ставити, можна написати `export NO_RUST=1` і білд пройде. В цілому доволі приємний досвід

Маленьке уточенння: \\?\ правильно називати extended-length, extended або verbatim, але не UNC. Бо UNC також може мати префікс \\?\ або бути без нього.

При тому, що на MSDN немає якогось словника від них саміх, я дивлюсь на те, як народ навколо називає. А там я чув тільки «UNC» для цього. Може, це і некоректно.
В головній статті щодо таких шляхів (тут) такого терміну немає. Є в іншій, але вона не декларативна, а рекомендаційна.
Ну, матиму на увазі, дякую. Але не змагатимусь з усталеним.