【问题标题】:Ignore .git folder in sub folder忽略子文件夹中的 .git 文件夹
【发布时间】:2014-05-06 06:46:15
【问题描述】:

是否可以将带有 .git 文件夹的子文件夹添加到存储库中,而 Git 不会将其视为子模块?我尝试了不同的方法来忽略该 .git 文件夹,但到目前为止没有任何效果。

我已经在 /.gitignore 中尝试过:

/vendor/**/.git/

..并在 /vendor/.gitignore:

.git/

我想忽略的 .git 文件夹在 /vendor/foo/bar/ 中。

【问题讨论】:

  • .git/ 被 git 自动忽略
  • 你能澄清你想要什么吗?您确定不是您的 Git GUI 客户端错误地将具有 .git 目录的子文件夹视为子模块吗?你用的是哪个 Git 客户端?
  • 12 次谷歌搜索后,Vinay Prajapati 提供了我在 cmets 中寻找的答案。

标签: git


【解决方案1】:

你试过通配符吗?

**/vendor/.git/

【讨论】:

    【解决方案2】:

    你的问题让我很感兴趣,所以我尝试了一下:

    $ cd /tmp
    $ git init foo
    Initialized empty Git repository in /private/tmp/foo/.git/
    $ cd foo
    $ git init bar
    Initialized empty Git repository in /private/tmp/foo/bar/.git/
    $ cd bar
    $ echo "this is bar" > bar.txt
    $ git add bar.txt
    $ git commit -m "initial commit"
    [master (root-commit) c9d6507] initial commit
     1 file changed, 1 insertion(+)
     create mode 100644 bar.txt
    $ cd ..
    $ pwd
    /tmp/foo
    $ git status
    On branch master
    
    No commits yet
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
            bar/
    
    nothing added to commit but untracked files present (use "git add" to track)
    $ git add bar
    $ git commit -m "parent initial commit"
    [master (root-commit) b23e106] parent initial commit
     1 file changed, 1 insertion(+)
     create mode 100644 bar/bar.txt
    $ echo "baz" > bar/.git/baz.txt
    $ git status
    On branch master
    nothing to commit, working tree clean
    

    根据您的问题,/tmp/foo 是一个 Git 存储库。对于/tmp/foo/tmp/foo/bar 是一个子目录,它本身有一个.git 目录。

    如您所见,父 foo 存储库完全忽略了 bar/.git 子目录,我什至不需要 .gitignore 文件。

    如果没有在 .gitmodules 文件中注册,Git 不可能将包含 .git 文件夹的路径视为子模块。

    【讨论】:

    • 我本可以发表评论,但我无法详细说明我用来得出结论的确切步骤。所以这是一个答案
    • 您的成绩单不符合我的期望,也不符合 git 文档,我自己也无法复制。你在哪个版本的 Git 上运行它?到目前为止,我已经尝试过 2.16 和 2.12 和 2.10。
    • git version 2.16.2 在 MacOS 上
    • 我可以在 Linux 上用2.16.2 重现它
    【解决方案3】:

    jthill answer 一样,您可以使用.git 添加子目录中的任何项目,它将被视为子目录而不是子模块。

    但是,如果您已经将此子目录注册为具有 .git 的子模块,则必须先删除该子模块,但将其保留在您的工作树中 - git rm --cached a/submodule

    更多信息: How do I remove a submodule?

    然后你可以从jthill answer重复步骤。

    根据我的研究,没有办法停止将 .git 文件夹视为子模块。所以我现在能想到的最好的解决方案是拥有bash 或任何可以在控制台的任何文件夹中运行的类似脚本。它应该找到任何具有.git 的子文件夹并尝试将该文件夹中的任何文件添加到主.git,因此它会停止将它们视为子模块。

    以下代码来源: Bash script to automatically convert git submodules to regular files

    #!/bin/bash
    
    # Get a list of all the submodules
    submodules=($(git config --file .gitmodules --get-regexp path | awk '{ print $2 }'))
    
    # Loop over submodules and convert to regular files
    for submodule in "${submodules[@]}"
    do  
       echo "Removing $submodule"
       git rm --cached $submodule # Delete references to submodule HEAD
       rm -rf $submodule/.git* # Remove submodule .git references to prevent confusion from main repo
       git add $submodule # Add the left over files from the submodule to the main repo
       git commit -m "Converting submodule $submodule to regular files" # Commit the new regular files!
    done
    
    # Finally remove the submodule mapping
    git rm.gitmodules
    

    请记住在尝试新脚本之前始终提交/备份更改,以防止任何工作/数据丢失。

    【讨论】:

      【解决方案4】:

      虽然.git 确实会被自动忽略,但主仓库会将/vendor/foo/bar 视为gitlink(主仓库索引中的特殊条目),而不是常规文件。

      一个技巧就是移动 bar/.git 主仓库之外:

      • vendor/foo/bar 将被视为常规子文件夹,如果需要,可以添加到主存储库中。
      • 如果您在git 命令之前使用GIT_DIR=/path/to/bar/.git git ...,则bar repo 可以随时检测更改并提交

      例如:

      cd /path/to/main/repo/vendor/foo/bar
      GIT_DIR=/path/to/bar/.git git status
      GIT_DIR=/path/to/bar/.git git add .
      GIT_DIR=/path/to/bar/.git git commit -m "changes to bar"
      GIT_DIR=/path/to/bar/.git git push
      

      【讨论】:

      • 替代语法:git --git-dir=/path/to/bar/.git status
      【解决方案5】:

      您可以通过首先直接添加一些(任何)内部内容来做到这一点。 Git 通过在搜索新遇到的目录时遇到 .git 条目来检测子模块,但如果你给它一个在该目录中查找的实际路径,它不会搜索。

      所以

      git add path/to/some/submodule/file     # bypass initial search that detects .git
      git add path/to/some/submodule          # now git's index has it as ordinary dir
      

      【讨论】:

        【解决方案6】:

        你可以使用 git hooks 来实现你想要的。开箱即用,您可以创建一个 pre-commit 挂钩来重命名包含项目的 .git 目录,例如。到“.git2”,添加后一个项目中除“.git2”目录外的所有文件,全部提交,推送,最后使用post-commit hook将“.git2”文件夹重命名为“ .git”在你的模块中。

        1) 在 root 存储库的 .git/hooks/ 下创建 pre-commit 文件,其内容为:

        #!/bin/sh
        mv "vendor/foo/bar/.git" "vendor/foo/bar/.git2"
        
        git rm --cached vendor/foo/bar
        git add vendor/foo/bar/*
        git reset vendor/foo/bar/.git2
        

        2) 在 .git/hooks/ 下创建 post-commit 文件,其中包含以下内容:

        #!/bin/sh
        mv "vendor/foo/bar/.git2" "vendor/foo/bar/.git"
        

        3) 更改您的存储库中的文件,最后:

        git commit -a -m "Commit msg"
        git push
        

        My Original answer

        【讨论】:

          【解决方案7】:

          您可以为此使用 Git 排除。

          首先,创建一个 .gitexclude 文件:

          $ echo "vendor/*/.git" >> .gitexclude
          

          然后将此文件添加到您的 Git 配置中作为排除源:

          $ git config core.excludesFile .gitexclude
          

          现在您可以添加文件,但 Git 不提供将它们添加为子模块:

          $ git add vendor
          $
          

          您可以使用git check-ignore 验证文件对 Git 确实“不可见”:

          $ git check-ignore vendor/foo/.git
          vendor/foo/.git
          $ git check-ignore vendor/foo/bar.txt
          $
          

          参考: 人 git-add(1) 人 git-check-ignore(1)

          【讨论】:

            猜你喜欢
            • 2016-04-09
            • 2018-08-31
            • 1970-01-01
            • 2011-02-02
            • 1970-01-01
            • 2018-06-25
            • 1970-01-01
            • 2019-07-14
            相关资源
            最近更新 更多