Git: can I suppress listing of 'modified content'/dirty submodule entries in status, diff, etc?
Asked Answered
D

9

163

Somewhen (around the 1.6.x releases, I think) git became aware of changes inside submodules. That only serves to annoy me:

$ git status vendor | grep modified:
#       modified:   vendor/rails (modified content)
$ git diff vendor/
diff --git a/vendor/rails b/vendor/rails
--- a/vendor/rails
+++ b/vendor/rails
@@ -1 +1 @@
-Subproject commit 046c900df27994d454b7f906caa0e4226bb42b6f
+Subproject commit 046c900df27994d454b7f906caa0e4226bb42b6f-dirty

Please make it stop?

Edit:

Ok, so I have an answer. Now I have another question:

Can I put this in ~/.gitconfig? From my initial it appears that I cannot, and I didn't see anything promising by skimming the patch. (I guess I can still make an alias.)

Devlin answered 13/7, 2010 at 19:47 Comment(0)
D
67

Update: See (and upvote) nilshaldenwang's answer regarding the possibility to add to the .gitmodules file a config parameter for ignoring dirty state of a given submodule.

ignore = dirty

So git 1.7.2 is out and includes the --ignore-submodules option for status.

From git help status:

--ignore-submodules[=<when>]
    Ignore changes to submodules when looking for changes.
    <when> can be either "untracked", "dirty" or "all", which
    is the default. When "untracked" is used submodules are
    not considered dirty when they only contain untracked
    content (but they are still scanned for modified content).
    Using "dirty" ignores all changes to the work tree of
    submodules, only changes to the commits stored in the
    superproject are shown (this was the behavior before
    1.7.0). Using "all" hides all changes to submodules (and
    suppresses the output of submodule summaries when the
    config option status.submodulesummary is set).

The value that I want is dirty.

git status --ignore-submodules=dirty

I use an alias because I'm lazy:

alias gst='git status --ignore-submodules=dirty'
Devlin answered 27/7, 2010 at 5:34 Comment(1)
Since this is an accepted answer, I think you should also add the option of adding ignore=dirty to individual entries in .gitmodules file here.Anesthesiologist
D
215

There is even a possibility to set the ignore mode for every added submodule within the .gitmodules file.

Just today I encountered this problem and immediately wrote an article in my blog about it after finding a solution: How to ignore changes in git submodules

The gist of it:

Once you added a submodule there will be a file named .gitmodules in the root of your repository

Just add one line to that .gitmodules file:

[submodule "bundle/fugitive"]
    path = bundle/fugitive
    url = git://github.com/tpope/vim-fugitive.git
    ignore = dirty
Deron answered 4/4, 2011 at 18:7 Comment(7)
+1, but I included the main part of your blog post to your answer on SO: your external link can become invalid one day, as opposed to SO answers which will live forever (through SO dumps: blog.stackoverflow.com/2009/06/…)Krasner
I found I needed to commit the .gitmodules file before git status worked as expected. Also you need at least 1.7.4 or better I believe.Nannie
For the .gitignore file, there is a private version called exclude, located in .git/info/, which is not version handled. Is there a corresponding file for the .gitmodules file, that will let you suppress changes in the submodule only in your instance of the parent repository, without making changes to .gitmodules?Paganism
I can't get this to work with a submodule tracking a branch. Is it not supported for that? ``` [submodule "smstack/ansible/hosts"] path = smstack/ansible/hosts url = https://... branch = master ignore = dirty ``` ```Bohemianism
@MarcAbramowitz I've stumbled upon the same issue I think - did you find any solution to this?Boelter
This didn't work for me - probably 'cos our legacy platform is using an ancient version of git - 1.7.1Peritonitis
external link can become invalid one day. Case in point: the external link is currently invalidWrapped
N
98

There are two kinds of change notices you can suppress.

The first is untracked content which happens when you make changes to your submodule but have not yet committed those. The parent repository notices these and git status reports it accordingly:

modified: modules/media (untracked content)

You can suppress these with :

[submodule "modules/media"]
   path = modules/media
   url = [email protected]:user/media.git
   ignore = dirty

However, once you commit those changes, the parent repository will once again take notice and report them accordingly:

modified:   modules/media (new commits)

If you want to suppress these too, you need to ignore all changes

[submodule "modules/media"]
   path = modules/media
   url = [email protected]:user/media.git
   ignore = all
Nannie answered 21/9, 2012 at 9:14 Comment(4)
For the .gitignore file, there is a private version called exclude, located in .git/info/, which is not version handled. Is there a corresponding file for the .gitmodules file, that will let you suppress changes in the submodule only in your instance of the parent repository, without making changes to .gitmodules?Paganism
HelloGoodbye: If you check .git/modules/$MODULENAME/ you'll see what seems to be the .git directory for that module. Changing the info/exclude file in that location does the job.Frictional
I want to give you a kissParamo
For anyone who, like me, wants to ignore changes to the submodule only locally (aka. without changes to .gitmodules), add ignore = all or whatever mode you want to your submodules section in .git/config.Itinerant
D
67

Update: See (and upvote) nilshaldenwang's answer regarding the possibility to add to the .gitmodules file a config parameter for ignoring dirty state of a given submodule.

ignore = dirty

So git 1.7.2 is out and includes the --ignore-submodules option for status.

From git help status:

--ignore-submodules[=<when>]
    Ignore changes to submodules when looking for changes.
    <when> can be either "untracked", "dirty" or "all", which
    is the default. When "untracked" is used submodules are
    not considered dirty when they only contain untracked
    content (but they are still scanned for modified content).
    Using "dirty" ignores all changes to the work tree of
    submodules, only changes to the commits stored in the
    superproject are shown (this was the behavior before
    1.7.0). Using "all" hides all changes to submodules (and
    suppresses the output of submodule summaries when the
    config option status.submodulesummary is set).

The value that I want is dirty.

git status --ignore-submodules=dirty

I use an alias because I'm lazy:

alias gst='git status --ignore-submodules=dirty'
Devlin answered 27/7, 2010 at 5:34 Comment(1)
Since this is an accepted answer, I think you should also add the option of adding ignore=dirty to individual entries in .gitmodules file here.Anesthesiologist
K
23

As you mention, the patch git submodule: ignore dirty submodules for summary and status is in the making.

Also announced in the Git 1.7.2-rc2 release:

Git v1.7.2 Release Notes (draft)
================================

Updates since v1.7.1
--------------------

"git status" learned "--ignore-submodules" option.

Meaning:

git config --global diff.ignoreSubmodules dirty

Regarding this as an option is not exactly the approach chosen for now:

After this series I am planning to add a config option 'ignore' to .gitmodules, which can be set for each submodule to either "all", "dirty", "untracked" or "none" (the default).

"git diff" and "git status" will use that config value for each submodule.
Using "--ignore-submodule" overrides this default (and the new parameter "none" will be added there to able to override the config settings).

And to avoid having to do "git submdule sync" every time that option changes, I would like to search for it in .git/config first.
If it is not found there, it will be taken from .gitmodules, if present.

So users can override the setting but if they don't, upstream can change it easily (e.g. when a submodules .gitignore has been updated so that "ignore=untracked" is no longer necessary anymore it can be removed).
Also switching branches will have an effect instantly if the 'ignore' entry in .gitmodules is different between branches.


Another approach to make git status (or any git command) to ignore a particular submodule is available with Git 2.13 (Q2 2017):

git config submodule.<name>.active false

See more at "Ignore new commits for git submodule".

Krasner answered 13/7, 2010 at 20:19 Comment(4)
I updated the question with a gitconfig bit. Just pinging in case you know the answer.Devlin
@kch: I have updated the answer with the approach currently proposed for storing this kind of setting.Krasner
@drozzy: as you mention in your other comment: "ignore = dirty"Krasner
Thanks, nothing personal, but I just wanted the more useful answer up-top, which I initially missed!Anesthesiologist
S
13

You can also use

% git config [--global] submodule.ignore dirty

to set submodule.ignore = dirty in your .git/config file. --global will set the ignore flag in your ~/.gitconfig and apply to all your repositories. Without it it should set in .git/config for just the repo you're in currently.

The only documentation I can find on this is submodule.<name>.ignore at the git-config docs. I moved it from a .gitmodules file into my ~/.gitconfig and it's still working for me.

Serious answered 4/8, 2011 at 2:19 Comment(1)
@PawełGościcki I can confirm it works on Git 2.0.0.Once
W
9

You need to add

ignore = dirty

to .gitmodules

Wideranging answered 28/11, 2011 at 8:3 Comment(2)
Where in .gitmodules do you add it to?Anesthesiologist
@drozzy You add it under the section for each submodule that you want to ignore, where the "path" and "url" values are defined.Nadya
W
4

I've answered this question here in greater detail.

Just run

git config --global diff.ignoreSubmodules dirty

to add a local config option to ignore those changes.

Wirehaired answered 11/9, 2018 at 13:26 Comment(0)
D
2

So git v1.7.2-rc2 has what I want:

$ git diff --ignore-submodules=dirty vendor
# no output
$ git status --ignore-submodules=dirty vendor
# On branch …
nothing to commit (working directory clean)

Building your own git howto:

# get git
git clone git://git.kernel.org/pub/scm/git/git.git git
cd git
git checkout v1.7.2-rc2

# make git. beware of setting prefix
make configure
./configure --prefix=/usr/local
make
sudo make install

# you REALLY don't want to `make doc`, use this instead
sudo make quick-install-man
sudo make quick-install-html
Devlin answered 13/7, 2010 at 20:35 Comment(1)
I count seven gits here: git clone git://git.kernel.org/pub/scm/git/git.git git.Humphrey
I
1

You may not want to add ignore = dirty to .gitmodules, you may want to be more selective about the changes you wished to ignore.

To do that, add patterns to .git/submodule_foo/bar/info/exclude, where submodule_foo/bar/ is the path of the submodule.

The patterns are similar to the patterns you would add to .gitignore, with the root being the submodule directory. For instance, this pattern ignores the build directory in the submodule submodule_foo/bar/:

# in .git/submodule_foo/bar/info/exclude:
/build/
Ianteen answered 18/4, 2016 at 10:22 Comment(1)
I think this will hide the changes also when inside a submodule. I only want the changes hidden when outside the submodule. It’s fine if they show up when inside, when I’m actively working on the submodule.Apeak

© 2022 - 2024 — McMap. All rights reserved.