77 lines
2.8 KiB
Python
77 lines
2.8 KiB
Python
"""Local (never global) Git provisioning for Windows into <repo>/.mingit/.
|
|
|
|
MinGit is the official minimal, portable Git for Windows — a plain zip meant
|
|
for embedding in tools (no installer, no registry, no PATH changes). On
|
|
Windows, if the system has no git, `manager sync` drops one here so updates
|
|
keep working from any terminal. The first clone (before this repo exists) is
|
|
handled the same way by the bootstrap layer (install.ps1 / desktop launcher),
|
|
which then moves its MinGit into the fresh checkout as .mingit/.
|
|
|
|
Linux and macOS have no sane portable git (glibc / Xcode CLT entanglement),
|
|
and git is effectively always available there — so this is Windows-only and
|
|
the manager just errors with install instructions elsewhere.
|
|
"""
|
|
|
|
import os
|
|
import platform
|
|
import shutil
|
|
import tempfile
|
|
|
|
from .util import IS_WINDOWS, REPO_ROOT, download, extract_archive, info, ok, warn
|
|
|
|
MINGIT_DIR = os.path.join(REPO_ROOT, ".mingit")
|
|
# Update this pin together with nothing else — it's independent of torch etc.
|
|
_MINGIT_TAG = "v2.55.0.windows.3"
|
|
_MINGIT_VERSION = "2.55.0.3"
|
|
|
|
|
|
def _mingit_url():
|
|
# git is a standalone subprocess (nothing dlopens it), so unlike
|
|
# node/ffmpeg it can be native arm64 on Windows-on-ARM
|
|
arm = platform.machine().lower() in ("arm64", "aarch64")
|
|
flavor = "arm64" if arm else "64-bit"
|
|
return "https://github.com/git-for-windows/git/releases/download/%s/MinGit-%s-%s.zip" % (
|
|
_MINGIT_TAG,
|
|
_MINGIT_VERSION,
|
|
flavor,
|
|
)
|
|
|
|
|
|
def local_git_exe():
|
|
return os.path.join(MINGIT_DIR, "cmd", "git.exe")
|
|
|
|
|
|
def find_git():
|
|
"""Path/command for git: repo-local MinGit first (Windows), then system."""
|
|
if IS_WINDOWS and os.path.isfile(local_git_exe()):
|
|
return local_git_exe()
|
|
return shutil.which("git")
|
|
|
|
|
|
def ensure_git(dry_run=False):
|
|
"""Windows-only: provision .mingit/ when the system has no git."""
|
|
if not IS_WINDOWS:
|
|
return False
|
|
if find_git():
|
|
return False
|
|
if dry_run:
|
|
info("[dry-run] would install MinGit into %s" % MINGIT_DIR)
|
|
return False
|
|
tmp = tempfile.mkdtemp(prefix="aitk_mingit_")
|
|
try:
|
|
archive = os.path.join(tmp, "mingit.zip")
|
|
download(_mingit_url(), archive, label="MinGit")
|
|
# MinGit zips have no top-level folder: cmd/, mingw64/, etc at the root
|
|
extracted = os.path.join(tmp, "mingit")
|
|
extract_archive(archive, extracted)
|
|
if not os.path.isfile(os.path.join(extracted, "cmd", "git.exe")):
|
|
warn("Unexpected MinGit archive layout — skipping local git install.")
|
|
return False
|
|
if os.path.isdir(MINGIT_DIR):
|
|
shutil.rmtree(MINGIT_DIR)
|
|
shutil.move(extracted, MINGIT_DIR)
|
|
ok("Local Git (MinGit) installed at %s" % MINGIT_DIR)
|
|
return True
|
|
finally:
|
|
shutil.rmtree(tmp, ignore_errors=True)
|