Git add .在子目录上失败,即使被忽略了一个.git文件夹,该如何处理?

4
我们有一个深层次的目录结构,不同层级上有多个README文档。例如:
gitignoretest/
|-- 00README
|-- dir1
|   |-- 00README
|   |-- dir1
|   |   |-- 00README
|   |   |-- dir1
|   |   |-- dir2
|   |   |-- dir3
|   |   |-- file1
|   |   `-- file2
|   |-- dir2
|   |   |-- 00README
|   |   |-- dir1
|   |   |-- dir2
|   |   |-- dir3
|   |   |-- file1
|   |   `-- file2
|   |-- dir3
|   |   |-- 00README
|   |   |-- dir1
|   |   |-- dir2
|   |   |-- dir3
|   |   |-- file1
|   |   `-- file2
|   |-- file1
|   `-- file2
|-- dir3
|   |-- 00README
|   |-- dir1
|   |   |-- 00README
|   |   |-- dir1
|   |   |   |-- 00README
|   |   |   |-- dir1
|   |   |   |-- dir2
|   |   |   |-- dir3
|   |   |   |-- file1
|   |   |   `-- file2
|   |   |-- dir2
|   |   |   |-- 00README
|   |   |   |-- dir1
|   |   |   |-- dir2
|   |   |   |-- dir3
|   |   |   |-- file1
|   |   |   `-- file2

...
...

我们希望仅对00README文件进行版本控制。我们已经使用这个.gitignore进行了成功测试。

.gitignore

# Ignore everything
*

# But not these files...
!.gitignore
!00README
# etc...

# ...even if they are in subdirectories
!*/

然而,在实际情况下,其中一个子目录是一个包含其自己的.git目录的conda安装。当我执行git add .时,它会出现以下错误消息:

fatal: Not a git repository: Applications/conda/lib/STAR-Fusion/STAR-Fusion.wiki/../.git/modules/STAR-Fusion.wiki

实际情况是 ../TopLevel/Applications/...../TopLevel/.gitignore。以下是我尝试过的方法:
../TopLevel/.gitignore
# Ignore everything
*
/Applications/conda/**/*
/Applications/miniconda3/**/*
/Applications/newconda/**/*

Applications/conda/**/*
Applications/miniconda3/**/*
Applications/newconda/**/*

/**/.git
**/.git

/**/.git/**
**/.git/**

# But not these files...
!.gitignore
!00README.md
!USE_APPS
# etc...

# ...even if they are in subdirectories
!*/

但没达到预期的目标。


编辑
针对 @VonC 提到的“取消跟踪”带有 .git 文件夹的子目录问题,我提供了一个全新创建的 git 仓库。注意:被添加为远程仓库的仓库是一个全新的 --bare 仓库。

balter@server:/home/.../TopLevel$ rmdir .git
balter@server:/home/.../TopLevel$ git init
Initialized empty Git repository in /home/.../TopLevel/.git/
balter@server:/home/.../TopLevel$ git remote add origin git@server.ohsu.edu:path/repo.git
balter@server:/home/.../TopLevel$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore
#   00README.md
#   Applications/
#   InstallationPackages/
#   USE_APPS
#   gitignoretest/
nothing added to commit but untracked files present (use "git add" to track)
balter@server:/home/.../TopLevel$ git add .
fatal: Not a git repository: Applications/conda/lib/STAR-Fusion/STAR-Fusion.wiki/../.git/modules/STAR-Fusion.wiki

你试过用 git add --all 而不是 git add . 吗?后者只适用于第一次提交,对吧? - mickdev
好的,那是第一次提交 :) 但我刚刚尝试了 git add --all,仍然得到了相同的错误 :( - abalter
不行。执行了 rmdir .git; git init; git remote add origin git@......git; git add . 仍然出现相同的错误 :( - abalter
好的,我已经没有想法了... 我认为最好的办法是手动从conda文件夹中删除git... 没有git,就没有错误。 - mickdev
我猜每次我们运行 conda update 时,它都会回来,而且可能有很多包都有这个问题 :( - abalter
显示剩余2条评论
1个回答

1
如果您想将整个树形结构视为一个存储库,则需要首先删除嵌套的.git子文件夹:参见“Initial push to GitHub Missing Sub Directory”。 关于忽略规则,如果您想忽略除OOREMEADE文件以外的所有内容,则需要先排除文件夹。
*
!**/

然后你可以排除文件:
!00README

请确保这些文件在被跟踪之前是未被跟踪的(git status

我们的应用程序目录中有一个conda安装,它似乎通过克隆git存储库来安装许多软件包。如果我删除所有的.git目录,那么每当我运行conda update时,要么会因为没有需要的存储库而失败,要么会重新克隆它们。

首先,不要忽略.git文件夹:它们的父文件夹表示一个嵌套的git repo。你要忽略的是该文件夹(.git文件夹的父级),这样git add .就不会记录一个gitlink父repo索引中的特殊条目

第二,"Not a git repository: .../../.git/modules/..." 表示 conda 嵌套存储库具有子模块,其conda 仍在进行中的支持:该 conda 安装文件夹需要 git submodule update --init --recursive 以初始化正确的嵌套子模块。

尝试一下。有几个问题:1)在我们的测试目录中,“它”可以工作,尽管没有文件夹本身是存储库。2)如果我理解正确,!**/是为了忽略实际上是文件夹而不是文件的任何内容。对吗? - abalter
@abalter 2)是的:如果一个文件夹被忽略了,任何涉及到该被忽略的子文件夹元素的规则都将不会被使用。1)有什么问题吗? ;) - VonC
尝试了上述方法,但仍然出现致命错误 :( 关于1)问题是,在测试目录(原始问题中显示的树形结构)中,我展示的.gitignore在忽略目录方面运行良好。那么为什么会在某个地方出现.git目录时失败呢?也许我需要忽略所有以“.”开头的目录? - abalter
这个程序相关的内容需要翻译成中文。请返回纯翻译文本:这是否充分解决了确保文件不被跟踪的问题? - abalter
@abalter,您的编辑似乎表明您仍然在新创建的git存储库中有嵌套的git存储库:请删除除git init创建的文件夹之外的任何.git子文件夹。 - VonC
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接