My employer produces a Windows desktop app and I maintain the GitLab CI and develop product installers using InstallAnywhere, among other things. We have a new product so I developed a functional installer for it. Our other products rely on a DLL library of ~6.5 GB called spaceLib
which sits in its own repo, and the new software relies a subset of this library (reduced to 200 MB), which is where my problem stems.
Our other software uses everything in spaceLib
, so my predecessor configured the other installer project repos with spaceLib
as a submodule
. Due to redundant maintenance of spaceLib
, file size, possible errors in maintenance (I might miss a file update to spaceLib
in my installer project repo), and the fact that I only need a fraction of the files, I first decided I’d perform a shallow clone of the spaceLib
subset into my new installer project when GitLab builds my installer but this results in empty files (1kB).
I wrote a batch script and use a file list to handle this:
@echo off
setlocal
echo CD is %CD%
:: Set vars
echo Setting environment variables...
set SCRIPTS_DIR=%~dp0
set BRANCH=dev
set SPACELIB_REPO=my.gitlab/installers/dependencies/spaceLib.git
set SPACELIB_DIR=windows64spaceLib
pushd source
:: Clone empty spaceLib repo
echo Cloning empty spaceLib repository...
git clone --branch %BRANCH% --no-checkout http://%SPACELIB_REPO% %SPACELIB_DIR% || goto GIT_ERROR
pushd %SPACELIB_DIR%
echo CD is %CD%
:: Restore necessary spaceLib files
echo Restoring necessary spaceLib files...
for /f %%F in (%SCRIPTS_DIR%spaceLib_components.txt) do (
echo Restoring file %%F...
git restore --staged %%F || goto GIT_ERROR
git restore %%F || goto GIT_ERROR
)
popd
popd
echo Cloning partial repositories successfull...
goto END
:GIT_ERROR
echo Failed one of the Git operations...
exit /b 1
:END
endlocal
When the script runs, spaceLib
is cloned into my installer project repo in sourcewindows64spaceLib
but all my files are empty (1kB). I started testing on my end and found the --no-checkout
option causes this. Why would the --no-checkout
option cause git restore
to produce empty files?
To my understanding, git clone
will fetch everything from the remote > download the git objects > rebuild the files in the index using the downloaded git objects > rebuild the files in the working area using what is in the index
. Adding the --depth=1
option will only fetch the latest commit. Adding the --no-checkout
option will fetch everything from the remote > download the git objects
and leave the index
and working area
empty. And running git restore
on each file in spaceLib_components.txt
would first restore my index
files to match my remote
, and then restore my working area
files to match my index
. I originally thought git was unable to reconstruct my files because of the --depth=1
restriction, but even after increasing the number of commits my files are still appearing as empty. If I run the command git clone --branch %BRANCH% http://%SPACELIB_REPO% %SPACELIB_DIR%
, I get my files as desired but end up with all the spaceLib
files. I’m not sure if I’m misunderstanding how --no-checkout
works or how git restore
works.
I’ve also read other posts on SO and see different suggestions on other possible solutions, I might use the last option for my case but don’t like that it can introduce more errors:
git clone --depth=1 <URL> <DIR>
to create a shallow clone (pulls all files)git clone --depth=1 --no-checkout <URL> <DIR>
to create a shallow clone without any files, thengit checkout pathtofile
to restore my file (results in empty files when I try this)- Create an empty git repo locally, set the remote origin, run
git config core.sparseCheckout true
, add the file subset I want to clone to.git/info/sparse-checkout
, and rungit pull