在Windows上构建嵌入式git以用于clone和pull
在 Windows 上构建嵌入式 git 以用于 clone 和 pull
在编写应用程序时,我们可能需要或倾向于使用 git 来克隆 GitHub 上的仓库,但又不希望要求用户必须提前安装完整的 Git 。如何构建一个嵌入式、绿色便携的 git 以供 git clone
和 git pull
?
获取 git-embed
从 GitHub Releases 页面 下载最新发布的的 "git-embed" 。国内用户可以从 这里 下载。
尝试
- 一种方式是使用 libgit2 ,其支持任何能够调用 C 语言库 的 编程语言 。
- 另一种方法是从 git-for-windows 中提取出能完成
git clone
和git pull
的最小程序集。
本文将尝试第二种方式。出于兼容性考虑,选择从 32 位的 Git 中提取构建,即 Git-2.26.2-32-bit.exe
、 MinGit-2.26.2-32-bit.zip
或 PortableGit-2.26.2-32-bit.7z.exe
。下文以 PortableGit-2.26.2-32-bit.7z.exe
为例。(其实 MinGit-2.xx.x-xx-bit.zip
更为合适)
git.exe
通过在已完整安装 Git 的 Windows 上运行 git --exec-path
可以知道 git.exe
位于 Git 安装目录下的 mingw64/libexec/git-core/
文件夹下。故可以(用 7-zip, WinRAR 等 )打开 PortableGit-2.26.2-32-bit.7z.exe
并解压之。准备一个未安装 Git 的 Windows7 虚拟机,复制 mingw32/libexec/git-core/git.exe
到虚拟机任意文件夹内。
DLL 依赖
可以预见只有一个 git.exe
必然无法完成 git clone
和 git pull
,我们需要找到还有哪些必要的 dll
库文件。
在当前目录打开 CMD 尝试执行 git
命令:
$ git
无法启动此程序,因为计算机中丢失 libiconv-2.dll。尝试重新安装该程序以解决此问题。
据此不断把 mingw32/libexec/git-core/
中相应的 .dll
文件复制到虚拟机内,与 git.exe
同一级目录即可。对于 v2.26.2
,可知必须的 dll
库文件有:
- libiconv-2.dll
- libgcc_s_dw2-1.dll
- libwinpthread-1.dll
- libintl-8.dll
- libpcre2-8-0.dll
- zlib1.dll
- libssp-0.dll
现在 git 能正确显示帮助信息了:
$ git
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
These are common Git commands used in various situations:
...
目前整体文件大小约为 5.15 MB ,经 zip 压缩后约为 2.58 MB 。
git clone
现在来测试 git clone
能否成功执行:
$ git clone https://github.com/LussacZheng/video-downloader-deploy.git
Cloning into 'video-downloader-deploy'...
warning: templates not found in /mingw32/share/git-core/templates
fatal: unable to find remote helper for 'https'
templates
的警告暂且不管。实际上只需要复制 mingw32/share/git-core/templates/
文件夹到 git.exe
所在目录,并指定 --template
参数即可:
$ git clone https://github.com/LussacZheng/video-downloader-deploy.git --template ./templates
Cloning into 'video-downloader-deploy'...
fatal: unable to find remote helper for 'https'
所以下文我会省略 --template
参数并刻意删去 warning: templates not found...
的警告信息。
而这个关于 https
的报错,我搜索到两种解决方案,先看最简单的方案。
https 错误 解决方案 1
将仓库地址中的 https://
替换为 git://
,即:
$ git clone git://github.com/LussacZheng/video-downloader-deploy.git
Cloning into 'video-downloader-deploy'...
error: cannot spawn git: No such file or directory
fatal: fetch-pack: unable to fork off index-pack
fatal: read error: Bad file descriptor
在 StackOverflow 上找到了 类似的问题。经尝试,只需要将 git.exe
所在目录加入环境变量 PATH
即可。
对于 CMD 窗口,可以使用 set
命令:( .\
是当前目录,实际嵌入后需要根据情况修改,如 set "PATH=%PATH%;D:\my\path\to\git\dir"
)
> set "PATH=%PATH%;.\"
> git clone git://github.com/LussacZheng/video-downloader-deploy.git
Cloning into 'video-downloader-deploy'...
remote: Enumerating objects: 70, done.
remote: Counting objects: 100% (70/70), done.
remote: Compressing objects: 100% (48/48), done.
remote: Total 70 (delta 33), reused 53 (delta 21), pack-reused 0Receiving objects: 34% (24/70), 1
Receiving objects: 100% (70/70), 15.56 KiB | 14.00 KiB/s, done.
Resolving deltas: 100% (33/33), done.
可以看到已经能够成功 clone
了。
https 错误 解决方案 2
git clone https://...
命令执行时实际上会调用 git-remote-https.exe
。另外 git-remote-http.exe
等同理。
既然如此,便将 git-remote-https.exe
复制到文件夹内。
$ git-remote-https
无法启动此程序,因为计算机中丢失 libcurl-4.dll。尝试重新安装该程序以解决此问题。
相似地,可以试出其还依赖于以下 dll
文件:
- libcurl-4.dll
- libcrypto-1_1.dll
- libidn2-0.dll
- libunistring-2.dll
- libnghttp2-14.dll
- libssh2-1.dll
- libssl-1_1.dll
只不过这样一来,会导致整体文件大小增加约 8.16 MB 。
REM set "PATH=%PATH%;.\"
> git clone https://github.com/LussacZheng/video-downloader-deploy.git
Cloning into 'video-downloader-deploy'...
fatal: unable to access 'https://github.com/LussacZheng/video-downloader-deploy.git/': error setting certificate verify locations:
CAfile: C:/Users/admin/Desktop/git/ssl/certs/ca-bundle.crt
CApath: none
对于 SSL 证书问题,可以:
复制
mingw32/ssl/certs/ca-bundle.crt
文件并指定-c http.sslcainfo=path/to/crt
:$ git clone https://github.com/LussacZheng/video-downloader-deploy.git -c http.sslcainfo=ca-bundle.crt Cloning into 'video-downloader-deploy'... remote: Enumerating objects: 70, done. remote: Counting objects: 100% (70/70), done. remote: Compressing objects: 100% (48/48), done. remote: Total 70 (delta 33), reused 53 (delta 21), pack-reused 0R Receiving objects: 100% (70/70), 15.56 KiB | 3.89 MiB/s, done. Resolving deltas: 100% (33/33), done.
`ca-bundle.crt` 会导致整体文件大小增加约 195 KB 。
- 或者还可以通过
-c http.sslverify=false
来取消 SSL 认证:$ git clone https://github.com/LussacZheng/video-downloader-deploy.git -c http.sslverify=false
git pull
现在来测试 git pull
能否成功执行。
可以创建一个测试项目,先在虚拟机内 clone
再在宿主机上 commit, push
一次。之后即可测试 git pull
。
$ git pull
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 1.06 KiB | 20.00 KiB/s, done.
From https://github.com/LussacZheng/test
b65c4e3..2141f21 pull-test -> origin/pull-test
Updating b65c4e3..2141f21
Fast-forward
another.txt | 5 +++++
new.txt | 2 ++
test.bat | 6 ------
3 files changed, 7 insertions(+), 6 deletions(-)
create mode 100644 another.txt
delete mode 100644 test.bat
$ git pull
Already up to date.
没有出现问题。
自动化提取与构建
我用 Node.js 简单写了一个自动化脚本,能够自动下载最新版本的 MinGit-<version>-<arch>-bit.zip
并从中提取构建出四种版本的 "git-embed" 。源码和发布文件都可以在 LussacZheng/git-embed 上找到,欢迎 Star, Issue 与 PR !
参考资料
Part 1 - 嵌入式 Git
- Embedding Git in your Applications / 中文
- minimal required files to just use git-clone - Google 网上论坛
- Minimum set of portable Git binary files(for Windows) for
clone
andpull
only - Stack Overflow - Posts containing 'portable git' - Stack Overflow
- Why Is libexec so huge? · msysgit/msysgit Wiki
- GitHub · git-for-windows/git , msysgit/msysgit
Part 2 - Git 细节问题
- git - fatal: Unable to find remote helper for 'https' - Stack Overflow
- Cygwin git fork() error on pull - Stack Overflow
- git - Github: error cloning my private repository - Stack Overflow