gitpushgit-submodules

Pushing git submodules correctly


I have the following repository layout:

Repo
|-- Folder1
|   |-- file1
|   |-- file2
|   ...
|-- Folder2
|   |-- file3
|   |-- file4
|   ...
|-- file5
|-- file6
...

Where 'Repo' is the main repository and 'Folder1' and 'Folder2' are two submodules.

Working with the root directory (file5, file6 in the example) is straight forward, but I have doubts about how to correctly push the items you modify inside the submodules.

Right now I'm editing the file inside each submodule, committing each change and pushing it localy:

[Repo]$ cd Folder1
[Folder1]$ vi file1
... do some changes ...
[Folder1]$ git add file1
[Folder1]$ git commit -m "Some changes"
[Folder1]$ git push

If I check git status on the submodule directly, it outputs that it's up to date:

[Folder1]$ git status
# On branch master
nothing to commit, working directory clean

But if I check the status in the root folder, it tells me that the submodule that I've already pushed, has new commits.

[Folder1]$ cd ..
[Repo]$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Folder1 (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")

Correct me if I'm wrong, but I suppose the above is due to git checking the current local repo commit ID vs the information in the git server I've pushed to. So, what I actually do now is commit all and push it up in the main repo. Is this the correct way to work with submodules?


Solution

  • [Repo]$ git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       modified:   Folder1 (new commits)
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    

    The above is due to the parent repository Repo pointing to an older commit of the Folder1 submodule.

    To your other question, yes, this is the correct way to work with submodules.

    1. Commit the submodule.
    2. Push the submodule.
    3. Commit in the parent repository.
    4. Push the parent repository.

    In this way you do not risk pushing a dangling submodule reference, i.e., a reference in the parent repository to a commit in the submodule that has not been pushed.

    Notice that, in the parent repository, is not mandatory that you commit and push every submodule update. Other users can work in the master branch of the submodule, and do a standard git fetch / git pull to download new revisions.

    I personally only commit a reference to a submodule when I'm going to release a new version of that submodule, to mark that release in the parent repository. My submodules are applications, and the parent repository is a shared library.