Combining CMake FetchContent and git --single-branch

31 Views Asked by At

I have a git repository with various dependencies distributed over separate branches (some of which take a lot of space). In a separate repository I have a CMake project which utilizes FetchContent to pull specific dependencies from their corresponding branches. The default behavior of git clone executed by ExternalProject_Add (which is called by FetchContent) is to fetch all existing branches - this means that all dependencies are downloaded even though FetchContent is told to only pull a specific branch - this causes a massive overhead due to downloading excessive data.

A direct solution to my issue is to perform git clone with --single-branch argument which allows to only fetch the target branch. However, due to reasons described here also visible in ExternalProject.cmake ExternalProject is explicitly telling git to not perform a single-branch clone.

The way I see is there's not many options to workaround this issue:

  • Make a separate repository for each dependency
    • I want to avoid this due to numerous dependencies being stored on the repo + for convenience purposes
  • Override FetchContent.cmake and ExternalProject.cmake
    • Is this even a good approach? The only change I would do is replacing --no-single-branch with --single-branch in ExternalProject.cmake
    • How does one even accomplish that? I copied both files to a path specified with CMAKE_MODULE_PATH, but it did not seem to work. Perhaps I did something wrong?
  • Giving up on using FetchContent completely and creating a custom implementation of dependency pulling for this specific purpose
    • Seems like lots of trouble

Is there any other solution (perhaps much easier and cleaner) to this issue or should I go with one of the above options?

I'd be grateful if you could point me in the right direction. Thanks in advance!

Problem example

I have a git repository with multiple branches - A, B, C. Let's assume that branch B contains very heavy data (e.g. 1GB) whereas most other branches are lightweight.

In a separate repository with a CMake project I want to pull specific branches which contain project dependencies. This is done using FetchContent:

FetchContent_Declare(
    A
    GIT_REPOSITORY [email protected]:X/Dependency_repository.git
    GIT_TAG        A
    GIT_SHALLOW    TRUE
    GIT_PROGRESS   TRUE
  )
  FetchContent_MakeAvailable(A)

Despite of performing a "shallow" clone, FetchContent causes all branches to be fetched resulting in a massive overhead. I only want to pull branch A, but B and C are also downloaded which takes up much more cloning time and disk space.

0

There are 0 best solutions below