Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git - check out branch and submodules

Which functions can I use to sync/init/update all submodules (local repo) to the version in a remote branch?

The "Sync" (let's call it that, I don't mean git sync!) must also work when:

  • A submodule has been added only to the remote branch
  • Files within a submodule have been added/removed/modified locally. Tracked or untracked.
  • Submodules are removed (optional)

Essentially, I want the local repo to always be at exactly the same version as the remote branch. Without much fiddling whenever I change somthing in the submodules. So no manual ssh'ing to the server to init a new submodule, only for the deploy script to work...

Can this be achieved without cloning (aka. transferring) the entire repository? I chose git to have a secure, fast way to deploy my sources. But the only option I can think of, is to do a complete git clone --recursive and check out submodules at their respective tags next. In which case, rsync would probably do a better job of syncing files.

like image 595
NoMad Avatar asked Mar 23 '26 00:03

NoMad


2 Answers

What about git submodule update --init --recursive? It will update the submodule to the right commit, initialize it if needed, and do this for all submodules, even when they are inside other submodules. If that doesn't discard changes, try git submodule foreach --recursive git reset --hard first.

like image 69
oyvind Avatar answered Mar 24 '26 16:03

oyvind


First, manually add and check out needed submodules at their desired location and version. To update all submodules, but keep their respective version that is checked out in the repo containing them, one can use

git submodule update --init --recursive --rebase --force

The --rebase will cause git to check out the exact commit, that the submodule is checked out at in the containing repo.

This will fail if the local repo has changes made to submodule files, so we have to reset all submodules first. For script usage:

git submodule foreach 'git reset --hard && git checkout . && git clean -fdx'
git submodule update --init --recursive --rebase --force

The reset commands were taken straight from git undo all uncommitted changes - Let me know if something else is more appropriate for this usecase.

No extra config required, just check out the submodule @ desired commit or tag and push that change in the containing repo.

These commands satisfy my first 2 initial requirements: As long as git tracks the submodule, all changes are fully sync'd to "clients" that run the commands. If a submodule is removed, git clean can be run on the repository containing the submodule(s) to delete orohaned submodule files.

like image 41
NoMad Avatar answered Mar 24 '26 16:03

NoMad