Dave Jarvis Dave Jarvis - 2 months ago 32
Git Question

Ignore new commits for git submodule

Background



Using Git 1.8.1.1 on Linux. The repository looks as follows:

master
book


The submodule was created as follows:

$ cd /path/to/master
$ git submodule add https://user@bitbucket.org/user/repo.git book


The
book
submodule is clean:

$ cd /path/to/master/book/
$ git status
# On branch master
nothing to commit, working directory clean


Problem



The master, on the other hand, shows there are "new commits" for the book submodule:

$ cd /path/to/master/
$ 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: book (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")


Git should ignore the submodule directory completely, so that the master is also clean:

$ cd /path/to/master/
$ git status
# On branch master
nothing to commit, working directory clean


Failed Attempt #1 - dirty



Inside the file
master/.gitmodules
is the following, as per this answer:

[submodule "book"]
path = book
url = https://user@bitbucket.org/user/repo.git
ignore = dirty


Failed Attempt #2 - untracked



Changed
master/.gitmodules
to the following, as per this answer:

[submodule "book"]
path = book
url = https://user@bitbucket.org/user/repo.git
ignore = untracked


Failed Attempt #3 - showUntrackedFiles



Edited
master/.git/config
to the following, as per this answer:

[status]
showUntrackedFiles = no


Failed Attempt #4 - ignore



Added the book directory to the master ignore file:

$ cd /path/to/master/
$ echo book > .gitignore


Failed Attempt #5 - clone



Added the book directory to the master as follows:

$ cd /path/to/master/
$ rm -rf book
$ git clone https://user@bitbucket.org/user/repo.git book


Question



How can the
book
submodule be in its own repository directory under the
master
repository yet have git ignore the
book
submodule? That is, the following should not display:

#
# modified: book (new commits)
#


How to suppress that message when executing
git status
in the master repository?

An article about git submodule pitfalls suggests this an inappropriate submodule usage?

Answer

To include another repository, that needn't be tracked in its super-repo, try this:

$ cd /path/to/master/
$ rm -rf book
$ git clone https://user@bitbucket.org/user/repo.git book
$ git add book
$ echo "book" >> .gitignore

Then commit.

As stated in the linked git submodule pitfalls article:

... the only linkage between the parent and the submodule is [the] recorded value of the submodule’s checked-out SHA which is stored in the parent’s commits.

That means that a submodule is not saved by its checked-out branch or tag, but always by a specific commit; that commit (SHA) is saved into the super-repo (the one containing the submodule) like a normal text file (it's marked as such a reference, of course).

When you check out a different commit in the submodule or make a new commit in it, the super-repo will see that its checked out SHA has changed. That's when you get the modified (new commits) line from git status.

To eliminate that, you can either:

  • git submodule update, which will reset the submodule to the commit currently saved in the super-repo (for details see the git submodule manpage; or
  • git add book && git commit to save the new SHA into the super-repo.

As mentioned in the comments, consider abandoning the book submodule: clone it inside the super-repo, if tracking of its state as part of the super-repo is not necessary.