在编写应用程序时,我们可能需要或倾向于使用 git 来克隆 GitHub 上的仓库,但又不希望要求用户必须提前安装完整的 Git 。如何构建一个嵌入式、绿色便携的 git 以供 git clone
和 git pull
?
从 GitHub Releases 页面 下载最新发布的的 “git-embed” 。国内用户可以从 这里 下载。
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
为例。(其实 )
通过在已完整安装 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
到虚拟机任意文件夹内。
可以预见只有一个 git.exe
必然无法完成 git clone
和 git pull
,我们需要找到还有哪些必要的 dll
库文件。
在当前目录打开 CMD 尝试执行 git
命令:
$ git
无法启动此程序,因为计算机中丢失 libiconv-2.dll。尝试重新安装该程序以解决此问题。
据此不断把 mingw32/libexec/git-core/
中相应的 .dll
文件复制到虚拟机内,与 git.exe
同一级目录即可。对于 v2.26.2
,可知必须的 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 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://
替换为 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
了。
git clone https://...
命令执行时实际上会调用 git-remote-https.exe
。另外 git-remote-http.exe
等同理。
既然如此,便将 git-remote-https.exe
复制到文件夹内。
$ git-remote-https
无法启动此程序,因为计算机中丢失 libcurl-4.dll。尝试重新安装该程序以解决此问题。
相似地,可以试出其还依赖于以下 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
能否成功执行。
可以创建一个测试项目,先在虚拟机内 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-
并从中提取构建出四种版本的 “git-embed” 。源码和发布文件都可以在 LussacZheng/git-embed 上找到,欢迎 Star, Issue 与 PR !
clone
and pull
only - Stack Overflow