1. 10
  1. 4

    Git does not have a concept of atomic commits across repositories. (…) Again, this is possible to work around with Git submodules – and get working in a way – but this requires discipline

    I can relate, but I have stopped believing in discipline.

    The problem is that, despite submodules being a builtin git feature, it does not offer the luxury of actually running git submodule update --init --recursive automatically – the developer is supposed to “remember” that!

    Here is why that’s completely unrealistic: As a developer, you go between branches and rebase your work on other people’s branches many times per day, and very seldom do you expect any submodule changes → in no way will you “remember” to interrupt your workflow with that pesky command – if the normal thing to do is to skip it, you skip it! Until there are submodule changes, the build has (hopefully) failed and you are complaining to your colleagues. Only then does it occur to you that maybe it’s the submodule that needs updating.

    What I prefer is to let the build system take care of it. Either:

    • Plan A: Use a dedicated build system feature instead, like CMake FetchContent or Meson subproject
    • Plan B: Actually use a git submodule, but write a hook that updates it when you build. In the case of Meson, you can use a git submodule as a meson subproject, and it will take care of it. In CMake and Make, you can implement it yourself.
    1. 2

      This is an excellent point, and updating + versioning is a reason to prefer e.g. Go modules. After a lot of stress trying to figure out how to handle a theme repository inside of the repository for my websites, at least when using the Hugo static site generator (written in Go), I’ve committed to Hugo modules:


    2. 1
      1. 3

        I’m not an everyday software developer, but the one time I tried git subtrees for an open source project (because the project’s maintainer hated submodules) I found it way more cognitive load compared to just using a submodule. If I recall correctly, using subtrees means you then have to remember to document the instructions of how to update the external source using git-subtree. So, in a sense, you then have two problems.