When I pull both a Git submodule repo and its enclosing repo, why do I then have local changes to commit?

╄→尐↘猪︶ㄣ 提交于 2019-12-23 01:12:12

问题


Let's say I have a Git repo R that has a subdirectory that is a submodule repo, SR.

On machine A I make changes to SR. I commit/push them. If I move up to the parent directory, git status will show that there are local changes. This (so far as I'm aware) is because the gitlink has been updated because the subrepo changed, and this needs to be committed and checked in. So I carry out the commit and push.

On machine B I go to the SR directory and execute a git pull. I then go to the enclosing folder in repo R (also on machine B) and execute a git pull.

Despite having made no local changes on machine B, git status will report that the subrepo has (new commits), i.e. it seems to expect me to commit these new changes. But why? For whose benefit are these "changes"? I can get my head around the idea of the changes to SR constituting a change for R. But if I've pulled both on B, why am I not 100% up to date, and why do I apparently have my own local changes that need to be committed?


回答1:


I can get my head around the idea of the changes to SR constituting a change for R.

That is because R references SR as a gitlink (special entry in the index of the parent repo), which represents the new SHA1 of SR.

You need to add, commit and push that new entry if you want others cloning R to get back SR at the right SHA1.

That means on B, you should not have to do a git pull from SR: it should already be checked out at the right commit.

If I execute a pull on R, why doesn't this automatically carry out the submodule update? Why does this need to be a separate action? Is the gitlink to SR not a part of the state of R that gets updated when I execute the pull on it?

Because a pull on R only update SR gitlink, not the actual checked out submodule SR.

Note: if you always have to do a pull inside a submodule, you could instead make sure SR follows its own master branch.

cd /path/to/your/parent/repo
git config -f .gitmodules submodule.<path>.branch <branch>

That way, a simple git submodule update --remote would be enough to pull and update SR from R.
As usual, if SR updates its HEAD, you will need to add, commit and push its new gitlink from R.




回答2:


The submodule function allows you to have a dependency not only toward another git repo, but also toward a certain commit of this repo.

When you pull the submodule you perform an action that's strictly restricted to the submodule's git clone.
When you perform a git pull there you're updating the submodule to latest.

Going back to the enclosing repo, that is using an older version of the submodule, git will think that you wanted to update the submobule to the latest version (because that's what you did with git pull).

Once in the enclosing repo, you need to do:

$ git submodule update

To reset your submodule to the state your enclosing git repo's HEAD depends on.

That's also something you will probably have to do every time you switch branches in the enclosing repo because each branch may depend on a different version of your submodule.



来源:https://stackoverflow.com/questions/40123696/when-i-pull-both-a-git-submodule-repo-and-its-enclosing-repo-why-do-i-then-have

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!