忽略git子模块的新提交

背景

在Linux上使用Git 1.8.1.1。 存储库看起来如下所示:

master book 

子模块创build如下:

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

book子模块是干净的:

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

问题

另一方面,主人显示书籍子模块有“新提交”:

 $ 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应该完全忽略子模块目录,这样master也是干净的:

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

失败的尝试#1 – 肮脏

根据这个答案 ,在文件master/.gitmodules是以下内容:

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

失败的尝试#2 – 没有跟踪

根据这个答案 ,将master/.gitmodules更改为以下内容:

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

失败尝试#3 – showUntrackedFiles

根据这个答案编辑master/.git/config到以下内容:

 [status] showUntrackedFiles = no 

失败尝试#4 – 忽略

将图书目录添加到主忽略文件中:

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

失败的尝试#5 – 克隆

将书目录添加到主文件中,如下所示:

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

book子模块如何在master存储库下的自己的存储库目录中,但是git忽略book子模块? 也就是说,下面不应该显示:

 # # modified: book (new commits) # 

如何在主资源库中执行git status时抑制该消息?

有关git子模块陷阱的文章表明这​​是不恰当的子模块用法?

要包含另一个仓库,不需要在其超级仓库中进行跟踪,请尝试以下操作:

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

然后提交。

正如链接的git子模块陷阱文章所述 :

…父节点和子节点之间唯一的联系是存储在父节点提交中的子节点检出的SHA的logging值。

这意味着一个子模块不会被其签出的分支或标签保存,而总是通过特定的提交来保存; 该提交(SHA)被保存到超级回购(包含子模块的那个)中,就像正常的文本文件(当然,它被标记为这样的引用)。

当你在子模块中签出一个不同的提交或者提交一个新的提交时,super-repo会看到它的签出的SHA已经改变了。 这是当你从git status获得modified (new commits)行。

要消除这一点,你可以:

  • git submodule update ,它会将子模块重置为当前保存在super-repo中的提交(详情请参阅git submodule页 ;或
  • git add book && git commit将新的SHA保存到super-repo中。

正如评论中提到的那样,考虑放弃book子模块:在超级回购中克隆它,如果作为超级回购的一部分进行跟踪是不必要的。

赶紧跑:

 $ git submodule update 

这会将子模块恢复为旧提交(在父回购中指定),而不更新子模块的最新版本的父回购。

有两种更改通知可以禁止(从git 1.7.2开始)。

第一个是未修改的内容,当您对子模块进行更改但尚未提交时发生。 父库会相应地注意到这些和git状态报告:

 modified: book (untracked content) 

你可以用下面的方法禁止

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

但是,一旦您提交这些更改,父存储库将再次注意并相应地报告:

 modified: book (new commits) 

如果你也想压制这些,你需要忽略所有的改变

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

Git 2.13(2017年第2季度)将增加另一种方式来包含一个子模块,该子模块不需要通过其父回购进行跟踪。

在OP的情况下:

 git config submodule.<name>.active false 

请参阅提交1b614c0 , 提交1f8d711 , 提交bb62e0a , 提交3e7eaed , 提交a086f92 (2017年3月17日),并提交由Brandon Williams( mbrandonw ) ee92ab9 , 提交25b31f1 , 提交e7849a9 , 提交6dc9f01 , 提交5c2bd8b (2017年3月16日) 。
(由Junio C gitster合并- gitster -于2017年3月30日提交a93dcb0 )

submodule :解耦URL和子模块的兴趣

目前submodule.<name>.urlconfiguration选项用于确定给定的子模块是否是用户感兴趣的。 在一个我们希望在不同的工作环境中检出不同子模块的世界里,或者一个更广义的机制来select哪个子模块是有意义的,这最终会变得很麻烦。

在未来工作支持子模块的情况下,将会有多个工作树,每个工作树可能只需要检出子模块的子集。
URL(可以获取子模块库的地址)不应该在不同的工作树之间有所不同。

用户可以更方便地指定他们感兴趣的子模块组,而不是在他们想要在工作树中检出的子模块上运行“ git submodule init <path> ”。

为此,引入了两个configuration选项: submodule.activesubmodule.<name>.active

  • submodule.activeconfiguration包含一个pathspec,指定工作树中应存在哪些子模块。
    • submodule.<name>.active config是一个布尔标志,用于指示工作树中是否应该存在特定的子模块。

需要注意的是, submodule.active函数与其他configuration选项不同,因为它需要一个pathspec。
这允许用户采用至less两个新的工作stream程:

  1. 子模块可以与一个主目录分组在一起,这样一个pathspec(例如' lib/ ')将覆盖所有的library-ish模块,以允许那些对library-ish模块感兴趣的人设置“ submodule.active = lib/ ” “ lib/ ”中的任何和所有模块都很有趣。
  2. 一旦发现了pathspec-attribute特性,用户就可以用属性标记子模块来将它们分组,这样就可以使用具有属性要求的广泛的pathspec,例如“ :(attr:lib) ”来说明任何和所有模块, lib '属性很有趣。
    由于.gitattributes文件就像.gitmodules文件一样被超级项目跟踪,所以当子模块在超级项目树中移动时,项目可以调整哪个path获得.gitattributes的属性,就像它可以调整哪个path具有子模块在.gitmodules

 git submodule update 

在根本上。