Как дать "git" доступ к определенным EXE-файлам, не добавляя весь каталог в среду $ PATH? - PullRequest
1 голос
/ 28 апреля 2019

Я использую MSYS2 / git с правильной установкой git для Windows SDK Установите git внутри MSYS2 правильно

git.exe находится в каталоге /mingw64/bin (который добавляется в $ PATH), но другие пакеты, которые нужны git (особенно такие как sh.exe и less.exe), находятся в каталоге /usr/bin, которого я не делаю хочу вставить $ PATH, чтобы не загрязнять мою среду другими исполняемыми файлами, такими как mkdir и dir, ...

В настоящее время некоторым командам git требуются такие пакеты, как git config -l, для которых требуется less, а любой команде git, которая откроет EDITOR, потребуется sh.exe.

Чего я хочу добиться - это добавить less и sh в PATH без добавления всего каталога.


Я пытался добавить их, используя методы ЗДЕСЬ и ЗДЕСЬ . Большинство из них позволяли мне использовать sh и less непосредственно из терминала, но ни одна из них не заставляла работать зависимые команды git.

Например, создание символической ссылки из less и sh в каталоге /mingw64/bin заставит командную строку распознавать эти исполняемые файлы, но использование git config -l не даст никакого вывода, если только каталог less был добавлен к $PATH.

Однако другие методы (создание сценариев и ярлыков, ..) заставят git жаловаться "Невозможно создать sh / less" , altgough cmd и powershell распознают less и sh.


Почему исполняемый файл будет работать с терминала, а не с git? Особенно в случае symlink , где git не жаловался на отсутствующие EXE-файлы, но все еще не работал должным образом?

Ответы [ 2 ]

1 голос
/ 29 апреля 2019

Моя хитрость для такого рода проблем заключается в замене "git.exe" на "git.bat", который выполняет что-то вроде set PATH=my\extra\dir;%PATH с последующим вызовом pass-all-args git.exe __git.exe %*. После создания такого BAT-файла я просто помещаю его в то же место, что и git.exe, переименовываю git.exe в __git.exe, и все готово. Всякий раз, когда я пишу «git checkout foo», он на самом деле вызывает файл BAT с параметрами «checkout foo», и BAT обрабатывает временное расширение переменной PATH или любые другие приготовления, которые я хотел бы получить.

Конечно, он не будет работать для внешних программ, которые хотели бы вызвать git.exe напрямую. Если внешняя программа вызывает git.exe, это не удастся. Если он вызывает git без расширения, он будет успешным, поскольку он попадет в файл BAT (при условии, что сама BAT находится в PATH).

В случае, когда git.exe нельзя «спрятать» за BAT-файлом (в этом случае я также уже сталкивался), я использовал аналогичное решение - я использовал файл .gitrc и поместил туда свои исправления. Вы можете увидеть пример более сложного gitrc здесь , в основном это просто скрипт оболочки, такой как bashrc / etc. Однако, как ни странно, я не могу найти каких-либо упоминаний в интернете относительно того, что обеспечивает запуск gitrc .. Я думал, что это сам git, но я не могу найти никакой вспомогательной ссылки. Одд.

1 голос
/ 29 апреля 2019

Звучит так, как будто вы хотите запустить Git для Windows вне MSYS2 и не хотите помещать весь каталог MSYS2 /usr/bin в свой PATH.Также, вероятно, будет хорошей идеей избегать добавления /mingw64/bin в вашу переменную PATH.

Я предлагаю создать программу-обертку для самого git.Он будет знать, где находится git.exe, и знать, какие каталоги помещать в PATH перед запуском git.exe.Он просто изменил бы PATH и затем передал бы все свои аргументы правильному git.exe.Поскольку вы, вероятно, используете оболочку, такую ​​как командная строка Windows, которая не распознает сценарии оболочки Bash, вам, вероятно, нужно просто создать статически связанный исполняемый файл Windows, который использует Win32 API для этого.Затем поместите его в свой собственный каталог и добавьте этот каталог в PATH.

Вот код, который должен работать для вас.Однако вам придется отредактировать MSYS2_DIR, чтобы он указывал на каталог, в котором вы установили MSYS2, и вам также придется редактировать строку target.(У большинства пользователей MSYS2 git установлен с pacman, и он находится в /usr/bin, поэтому я не хотел жестко кодировать что-то другое в этот код.)

#include <windows.h>
#include <stdio.h>

#define MSYS2_DIR "C:/msys64"

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  LPSTR lpCmdLine, int nShowCmd)
{
  const char * target = MSYS2_DIR "/usr/bin/git.exe";

  BOOL success = SetEnvironmentVariable(
    "PATH", MSYS2_DIR "/mingw64/bin;" MSYS2_DIR "/usr/bin/");
  if (!success)
  {
    DWORD error = GetLastError();
    fprintf(stderr, "Failed to set PATH: error %ld.\n", error);
    return 1;
  }

  PROCESS_INFORMATION info;

  STARTUPINFOA startup_info = {
    sizeof(startup_info),
    .hStdInput = GetStdHandle(STD_INPUT_HANDLE),
    .hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE),
    .hStdError = GetStdHandle(STD_ERROR_HANDLE),
  };

  success = CreateProcessA(target, GetCommandLine(),
    NULL, NULL, 1, 0, NULL, NULL, &startup_info, &info);
  if (!success)
  {
    DWORD error = GetLastError();
    fprintf(stderr, "Failed to start git: error %ld.\n", error);
    return 1;
  }

  DWORD result = WaitForSingleObject(info.hProcess, INFINITE);
  if (result)
  {
    fprintf(stderr, "Unexpected wait result: 0x%lx\n", result);
    return 1;
  }

  DWORD code;
  success = GetExitCodeProcess(info.hProcess, &code);
  if (!success)
  {
    fprintf(stderr, "Failed to get child exit code.\n");
    return 1;
  }
  return code;
}

Вы можете скомпилировать это, используя 32-бит или 64-битные наборы инструментов MinGW, которые предоставляет MSYS2.Просто запустите gcc wrapper.c -o git.Это должно создать собственный исполняемый файл Windows без каких-либо зависимостей ни от каких библиотек MSYS2.

...