【问题标题】:How to tell git to ignore git sub modules?如何告诉 git 忽略 git 子模块?
【发布时间】:2014-06-15 06:59:00
【问题描述】:

我的“真实”.git 文件夹位于/var/www。我想将整个文件夹推送到 github。不幸的是,一些 git 子模块被排除在外。

例如,文件夹w/extensions/Lingo 被排除在外。但是w/extensions/Lingo/.git 不是“我的”git 子模块。 Git 仅用于下载 w/extensions/Lingo 并将用于更新该文件夹。没有自己的开发计划。

我怎样才能告诉我的“真正的” git /var/www/.git 忽略任何子模块,例如 w/extensions/Lingo/.git

换句话说,我想告诉 git 是“将/var/www/* 中的任何文件视为普通文件”。

【问题讨论】:

    标签: git git-submodules


    【解决方案1】:

    www/extensions/Lingo 不应被忽略:您将推送的是 gitlink (special entry, mode 16000),它代表(在主 repo 的工作树中)当前在 www/extensions/Lingo 中签出的 SHA1。

    您可以通过 git log(不带斜杠)来检查:

    cd /var/www
    git log -- extensions/Lingo
    

    【讨论】:

    • 我不想忽略它,而是将其视为普通文件夹。该怎么做?
    • @adrelanos 它是一个子模块:它不应该被视为一个普通文件夹,而是作为另一个 repo 内容的标记:一旦你克隆了你推送到 GitHub 的内容,一个简单的git submodule update --init 将恢复该文件夹的内容。
    • 我把它推到了github。当有人克隆它时,他们最终会得到一个空的/www/w/extensions/Lingo。不是我想要的。
    • @adrelanos 是的,这是您对子模块的期望:​​它不是一个空文件夹,而是一个特殊的图标:stackoverflow.com/a/19585206/6309 这是我在我的回答。
    • @adrelanos 请记住,这不仅仅是将子模块“视为常规文件夹”:它是关于存储确切版本(如果该文件夹内容)。
    【解决方案2】:

    如果您坚持在您的 repo 中包含子模块的内容,您可以这样做:

    git submodule deinit Lingo 
    git rm -r --cached extensions/Lingo
    rm -R extensions/Lingo/.git # (if it is still there)
    git add extensions/Lingo
    

    (正如我在“How do I remove a Git submodule?”中详述的那样)

    --cached 确保您没有删除工作树中该文件夹的内容。

    【讨论】:

    • 这可能行得通,但是使用简单的git fetch + git merge origin/master 更新扩展程序/Lingo 的能力就会丢失。
    • @adrelanos 当然,这就是为什么它是一个子模块!最后一种选择是使其成为子树:blogs.atlassian.com/2013/05/…(但请注意stackoverflow.com/a/14448784/6309
    • @adrelanos 其他选择:jayunit100.blogspot.fr/2013/12/… 但我只会保留子模块;)
    • 我觉得有正当的理由杀死 git 中的子模块触发器。我刚刚在一个更大的客户端项目内的文件夹中添加了一个新的 ember.js 项目。由于运行 'ember new my-ember-project' 在 'my-ember-project' 文件夹内创建了一个 .git 文件夹,因此该项目的主要存储库希望将其作为子模块拾取。它实际上不是子模块,而是由 ember cli 生成的,以方便使用。为了让父 repo 实际上将其作为一组文件进行跟踪,上述命令(主要是 rm -R my-ember-project/.git 部分)对解决问题非常有帮助。
    • @MySpecialPurpose 做得好:这确实会使该回购的内容可见,而不是成为嵌套回购的一部分。
    【解决方案3】:

    我不建议这样做,但听起来你已经死定了...请注意,这会导致“子模块”中的文件在两个地方提交,并保持它们的同步将是一个额外的挑战。

    我的看法是,这至少和子模块一样复杂,因为这是一件很奇怪的事情,所以其他想要贡献的开发人员可能会感到困惑。

    可以.git 目录移出您的子模块目录,以便

    1. 您的主 Git 存储库不会将“子模块”目录视为子模块,并且
    2. 您仍然可以从上游获取。

    这是一个简短的例子:

    1. 将某些内容(您的“内部存储库”)克隆到主存储库的子目录中:

      ~ $ cd repo
      ~/repo/ $ git clone git://some-other-repo.git/
      
    2. 创建一个目录来保存内部存储库中位于主存储库之外的.git 目录,并将内部.git 目录移动到那里:

      ~/repo/ $ cd ..
      ~ $ mkdir -p fake-submodules/some-other-repo/
      ~ $ mv ~/repo/some-other-repo/.git fake-submodules/some-other-repo/
      
    3. 现在,您可以从您的主存储库添加所有文件并照常提交:

      ~ $ cd repo
      ~/repo/ $ git add some-other-repo
      ~/repo/ $ git commit -m "Add some other repo"
      
    4. 您可以使用 Git 的 --work-tree 选项从上游存储库获取更新:

      ~/repo/ $ cd ../fake-submodules/some-other-repo
      ~/fake-submodules/some-other-repo/ $ git --work-tree ../../repo/some-other-repo status
      ~/fake-submodules/some-other-repo/ $ git --work-tree ../../repo/some-other-repo fetch
      ~/fake-submodules/some-other-repo/ $ git --work-tree ../../repo/some-other-repo merge origin/master
      

    请注意,您必须从内部存储库的fake-submodules 目录执行所有 Git 操作。您可能需要执行git config core.worktree ../../repo/some-other-repo 之类的操作,以避免每次都输入--work-tree 选项。

    再次,请重新考虑这样做。 Git 的子模块可能并不完美,但至少它们被广泛使用和理解。正如 VonC 所说,还有其他更合适的选项,例如子树。

    【讨论】:

      猜你喜欢
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 2013-01-03
      • 2012-04-10
      • 2015-02-06
      • 2010-11-17
      • 1970-01-01
      • 2021-08-23
      相关资源
      最近更新 更多