0

I have a repo containing submodules which i manage from multiple machines. I updated the repro from machine1 wherein i removed some submodules using the following steps:

  • git submodule deinit path_to_submodule
  • git rm path_to_submodule
  • rm -rf .git/modules/path_to_submodule

After pushing my changes to the remote, i want to pull the changes in my machine2 so that the submodules that i deleted in machine1 get deleted in machine2 as well.

What is the command to do it.? I don't think git pull is sufficient for this.

I tried git submodule update --recursive but no luck

Haris Muzaffar
  • 404
  • 6
  • 17

1 Answers1

0

For various and mostly-historic reasons, a git checkout that:

  • moves away from a commit (and corresponding index / staging-area) that has a submodule that lives in path/to/submodule
  • moves to a commit that that lacks anything in path/to/submodule

does not remove the submodule. The path/to/submodule in the working tree, from a previous checkout, is a directory, and is not in Git's index any more. It's just a directory in someone's working tree, similar to any other directory or untracked file in someone's working tree. Hence, as you say, git pull—which runs git fetch followed by a second Git command whose details we'll just ignore here1—also does not remove the submodule.

I tried git submodule update --recursive but no luck

Since the submodule is now, after updating, not something Git knows anything about, that won't do anything about it either.

You could use git clean, which can remove files that Git doesn't know anything about. It seems simpler and safer, though, just to run rm -rf on the unwanted directory. Why do you need Git specifically to do this?2


1The details do matter, and—depending on which command is run second, and what the inputs are to this command—there are many different possible results, but each of them ends up with "did not remove the submodule".

2It's certainly inconvenient that Git won't clean up after itself, but the reason it doesn't gets us right back into that "mostly historic" part. Back in the Dim Time, the submodule's repository for path/to/submodule lived right there in path/to/submodule/.git. That repository's working tree was therefore right there in path/to/submodule, where it remains today when the submodule is checked out. Today, after you run git submodule absorbgitdirs—or initially, if Git clones and checks out the repository itself using a modern Git—the repository is in the superproject's .git/modules/, i.e., the path you mention in your own question. But Git still supports this historic mode.

If Git removed the submodule work-tree, that would of necessity force Git to remove the repository as well. That repository could be the only clone, and might have stuff in it that was never saved anywhere else. So that would be a dreadful error, and therefore, Git must never remove it.

Of course, nobody actually uses this still-supported historic mode. Except, that is, for all the people who are using it. See also https://xkcd.com/2347/

torek
  • 448,244
  • 59
  • 642
  • 775