Table of Contents
Introduction
Problem
Git offers submodules, a great way to manage your projects in a modular way. The problem with that is well summarized by this question on StackOverflow. In short, every low-level library from your project is likely to be pulled in more than once, and so you will have multiple copies of each.
Solution
The solution is also provided on the same StackOverflow page. Git allows you to share a repository and make submodules all point to the same copy on your hard disk. This means that if you modify or update any of the cloned repositories, any repository referencing it will be affected. This might or might not be what you want.
About the script
All the flat_git script does is automating the process explained the the Solution section. You don't really need to run this script to apply this technique, and you don't need to keep using the script at any point.
The obvious problem left at this point is that, irrespectively of if you decide to use the flat_git script, if you apply the above technique you will end up with subdirectories in your project that are empty instead of containing the usual submodule. Or maybe the do contain the submodule's working tree. You need to tweak your build system to deal with this.
A CMake script is provided to deal with this scenario if you are using CMake for your project. See the Example section for a practical example.
Usage
Example
In this example let's say you have one CMake project per git repository, for a total of 3 projects. top_project is the main one, and it depends on libraries sub_1, sub_2. Project sub_1 also depend on sub_2.
CMakeLists.txt - everything is just the same as usual, except that you use add_shared_git_project
instead of the regular add_subdirectory
.
project(top_project CXX)
include(shared_git_project)
add_executable(top_project main.cpp)
add_shared_git_project(lib/sub_1)
add_shared_git_project(lib/sub_2)
lib/sub_1/CMakeLists.txt
project(sub_1)
include(shared_git_project)
add_library(sub_1 lib1.cpp)
add_shared_git_pcoject(lib/sub_2)
target_include_directories(sub_1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
lib/sub_2/CMakeLists.txt
project(sub_2)
add_library(sub_2 lib2.cpp)
target_include_directories(sub_2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
This will clone the main git repository and the sub_1 and sub_2 directories inside the shared/ directory. After doing this you are good to go!
git clone https://github.com/dummy/top_project.git
mkdir shared
cd top_project.git
flat_git ../shared