Reputation: 2571
Let's say I have a parent repo myproject
, and a separate repo called submodule
, with the directory structure that's the following:
root$ find . -not -path *.git* . ./myproject ./myproject/submodule
Now I add submodule
as a submodule to myproject
.
root$ cd myproject myproject$ git submodule add git://url-to-submodule:submodule.git submodule Adding existing repo at 'submodule' to the index
Now, let's say i change something to submodule
.
myproject$ cd submodule submodule$ touch herpin.txt submodule$ add herpin.txt submodule$ git commit -am "i'm herpin and i'm derpin"
At this point, I go back to the parent repository, and check the git status:
submodule$ cd .. myproject$ git status # On branch master # Changes not staged for commit: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: submodule (new commits) # no changes added to commit (use "git add" and/or "git commit -a")
Well, damn it -- now each time I commit something in submodule, I also have to commit the parent.
It gets annoying pretty quickly if you have a more complex submodule tree. Let's say -- 4-levels deep. If I make a change at the inner-most submodule, I have to commit its parent, its grandparent, its great-grandparent, and its great-great-parent. That's a freaking pain in the ---.
There must be a better way! (And no, not nesting so many levels isn't an option. :/ That's not my call to make ...) Isn't there a way where git-commit can notify the parent repositories of the commit?
Upvotes: 16
Views: 10601
Reputation: 1233
When you make changes to the submodule, you can push your uncommited changes to the remote repository without touching your parent projects as following:
cd submodule
.git stash
git pull <remotename> <branchname>
git checkout <branchname>
git stash pop
git add
, git commit
git push <remotename> <branchname>
.Now you have commited changes in your submodule locally and pushed them to your remote repository. In your main project .gitmodules
should be updated and point to the last commit you made in your submodule directory. Now it's your choice to either commit your .gitmodules
file to use a commit with updated submodule, or you can discard and continue using old and not updated submodule. But if you discard and run git submodule update --remote
, it will pull that old not updated branch, so you probably want to commit this .gitmodules
file in your main project as well.
Here's a chapter about it from the Pro Git book: https://git-scm.com/book/en/v2/Git-Tools-Submodules
Upvotes: 1
Reputation: 4470
Committing to a submodule should be treated like committing to another external library / repository.
Don't use git status on the root, use it on the submodule.
No you don't need to commit the changes in the container, you only need to commit them from within the sub module.
You can then make several changes, roll back, keep the submodule on a stable branch etc, and then only update the parent container to a stable version of the submodule.
Updating a submodule reference shouldn't be done constantly, and should only really swing between compatible versions, otherwise you will have a ton of 'bump' commits in a row that's just updating the sub module as you found out.
So in short, do your work in a submodule, commit, do more work in a submodule commit. Then once done, update the submodule reference to either the new version by committing the container, or rolling back the submodule to the last stable version, leaving the commits for future dev work.
Upvotes: 1