0

I know there is already one question on this at Stackoverflow. But it talks about how to avoid such situation where we want to ignore new commits from the start. I already have a Go repo which has go-build directory which is a submodule in itself. When I do git status, I am getting the following message:

On branch x/y
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:   go-build (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

Is it possible to keep the change locally but to avoid pushing the commits in go-build to master? I saw there is a way to do it for directories/file by adding them to .git/info/exclude file but that didn't work for the submodule.

blackmamba
  • 1,952
  • 11
  • 34
  • 59

1 Answers1

0

Is it possible to keep the change locally but to avoid pushing the commits in go-build to master?

Yes, of course this is possible. Whether it's a sensible thing to do, and how you want to go about doing it, is another question entirely.

The key here is understanding that each submodule is its own, separate, private repository. The superproject—the Git repository that refers to the submodule—has three pieces of information stored in it. Two of those are what you would pass to git clone in order to obtain the submodule repository:

git clone <url> <path>

The third piece of information is stored in each commit1 in the superproject, and that is the raw hash ID of the one specific commit that the above git clone should check out after the clone finishes.

If your submodule has new commits that you don't deliver elsewhere, but in your superproject, you do record the hash ID of one of these new commits that does not exist anywhere else, then:

  • anyone else who runs the git clone will get a clone of the submodule, but
  • when their superproject Git goes to git checkout the specified hash ID, that hash ID won't exist in their submodule clone

so they will get an error.

On the second hand, if you don't record the new hash ID in the superproject, then whoever is doing a clone of your superproject, and asks their clone to clone the submodule as well, will check out the old hash ID, which will be fine—but they'll have a different submodule checked out than you do. Their build may or may not work, depending on what has changed in the submodule.

On the third hand,2 you can always just go ahead and commit the new hash ID in the superproject, because your superproject presumably already has earlier commits that work with the earlier version of the submodule. So anyone who has the problem outlined in the "first hand" stage can just check out an earlier commit in the superproject. For that matter, there's no requirement that you push this particular superproject commit anywhere—in which case, other users of the superproject will never even see this commit that has the new hash ID for the submodule. The problem just does not arise, in this case.

Hence, it is all a matter of what you want as the result.


1Technically it's in a tree object, either the top level tree object of the commit, or some sub-tree, depending on the <path> for the submodule. The key distinction between this and the other two pieces of information is that the other two are in an ordinary file that anyone can read or edit: a file named .gitmodules. The commit hash ID is stored in an internal-use Git object, that users do not normally ever see directly.

2Either the gripping hand, or the first foot, perhaps.

torek
  • 448,244
  • 59
  • 642
  • 775