163

对于我原来的问题,请参见实线下方。

我的本地目录中有一个未跟踪的文件夹。当我运行时git status,我得到:

Changed but not updated:
modified:   vendor/plugins/open_flash_chart_2 (modified content, untracked content)

当我输入git add vendor/plugins/open_flash_chart_2然后再试git status一次时,它仍然显示未跟踪。这是怎么回事?


以下是我最近半小时的简单总结:

  • 发现我的 Github repo 没有跟踪我的vendor/plugins/open_flash_chart_2插件。具体来说,没有内容,它在文件夹图标上显示一个绿色箭头

  • 试过了git submodule init

    No submodule mapping found in .gitmodules for path 'vendor/plugins/open_flash_chart_2'
    
  • 试过了git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

    vendor/plugins/open_flash_chart_2 already exists in the index
    
  • git status

    modified: vendor/plugins/open_flash_chart_2 (untracked content)
    
  • 寻找在我的存储库/本地目录中命名的任何文件.gitmodules,但找不到。

我该怎么做才能让我的子模块正常工作,以便 git 可以开始正确跟踪?


这可能是无关的(我包括它以防它有帮助),但每次我输入git commit -a而不是我通常的输入git commit -m "my comments"时,它都会抛出一个错误:

E325: ATTENTION
Found a swap file by the name ".git\.COMMIT-EDITMSG.swp"
         dated: Thu Nov 11 19:45:05 2010
     file name: c:/san/project/.git/COMMIT_EDITMSG
      modified: YES
     user name: San   host name: San-PC
    process ID: 4268
While opening file ".git\COMMIT_EDITMSG"
         dated: Thu Nov 11 20:56:09 2010
  NEWER than swap file!  
Swap file ".git\.COMMIT_EDITMSG.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
Swap file ".git\.COMMIT_EDITMSG.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:

我是 Github 的新手,尽管尝试浏览文档,但我还是被这些特殊问题难住了。谢谢你。

4

14 回答 14

243

您已添加vendor/plugins/open_flash_chart_2为“gitlink”条目,但从未将其定义为子模块。实际上,您正在使用git submodule使用的内部功能(gitlink 条目),但您没有使用子模块功能本身。

你可能做了这样的事情:

git clone git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2
git add vendor/plugins/open_flash_chart_2

最后一个命令是问题所在。该目录vendor/plugins/open_flash_chart_2最初是一个独立的 Git 存储库。通常这样的子存储库会被忽略,但是如果你告诉git add显式添加它,那么它将创建一个指向子存储库的 HEAD 提交的 gitlink 条目,而不是添加目录的内容。如果git add拒绝创建这样的“半子模块”可能会很好。

普通目录在 Git 中表示为树对象;树对象为它们包含的对象(通常是其他树和 blob 对象——分别为目录和文件)提供名称和权限。子模块表示为“gitlink”条目;gitlink 条目仅包含子模块的 HEAD 提交的对象名称(哈希)。gitlink 提交的“源存储库”在.gitmodules文件中指定(以及.git/config子模块初始化后的文件)。

您所拥有的是一个指向特定提交的条目,而没有记录该提交的源存储库。你可以通过将你的 gitlink 变成一个适当的子模块来解决这个问题,或者通过删除 gitlink 并将其替换为“正常”内容(普通文件和目录)。

把它变成一个适当的子模块

您缺少正确定义vendor/plugins/open_flash_chart_2为子模块的唯一一点是.gitmodules文件。通常(如果您尚未将其添加为裸 gitlink 条目),您只需使用git submodule add

git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

如您所见,如果路径已存在于索引中,这将不起作用。解决方法是暂时从索引中移除 gitlink 条目,然后添加子模块:

git rm --cached vendor/plugins/open_flash_chart_2
git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

这将使用您现有的子存储库(即它不会重新克隆源存储库)并暂存一个.gitmodules如下所示的文件:

[submodule "vendor/plugins/open_flash_chart_2"]
    path = vendor/plugins/open_flash_chart_2
    url = git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

它还将在您的主存储库中创建一个类似的条目.git/config(没有path设置)。

提交它,您将拥有一个适当的子模块。当您克隆存储库(或推送到 GitHub 并从那里克隆)时,您应该能够通过git submodule update --init.

用纯内容替换它

下一步假设您的子存储库中vendor/plugins/open_flash_chart_2没有您要保留的任何本地历史记录(即您只关心子存储库的当前工作树,而不是历史记录)。

如果您关心的子存储库中有本地历史记录,那么您应该备份子存储库的.git目录,然后在下面的第二个命令中将其删除。(还要考虑下面的git 子树示例,它保留了子存储库 HEAD 的历史记录)。

git rm --cached vendor/plugins/open_flash_chart_2
rm -rf vendor/plugins/open_flash_chart_2/.git # BACK THIS UP FIRST unless you are sure you have no local changes in it
git add vendor/plugins/open_flash_chart_2

这次添加目录时,不是子库,所以会正常添加文件。不幸的是,由于我们删除了.git目录,因此没有超级简单的方法可以让源存储库保持最新状态。

您可以考虑改用子树合并。这样做可以让您轻松地从源存储库中提取更改,同时在存储库中保持文件“平坦”(无子模块)。第三方git subtree命令是子树合并功能的一个很好的包装器。

git rm --cached vendor/plugins/open_flash_chart_2
git commit -m'converting to subtree; please stand by'
mv vendor/plugins/open_flash_chart_2 ../ofc2.local
git subtree add --prefix=vendor/plugins/open_flash_chart_2 ../ofc2.local HEAD
#rm -rf ../ofc2.local # if HEAD was the only tip with local history

之后:

git remote add ofc2 git://github.com/korin/open_flash_chart_2_plugin.git
git subtree pull --prefix=vendor/plugins/open_flash_chart_2 ofc2 master

git subtree push --prefix=vendor/plugins/open_flash_chart_2 git@github.com:me/my_ofc2_fork.git changes_for_pull_request

git subtree还有一个--squash选项可以让您避免将源存储库的历史合并到您的历史中,但仍然可以让您拉入上游更改。

于 2010-11-12T08:06:31.423 回答
114

我只是有同样的问题。原因是因为有一个包含“.git”文件夹的子文件夹。删除它让 git 很高兴。

于 2011-05-05T13:02:29.877 回答
15
  1. 我从那些新目录中删除了 .git 目录(这可以创建子模块戏剧。如果有兴趣,谷歌它。)
  2. 然后我跑了 git rm -rf --cached /the/new/directories
  3. 然后我用 git add 重新添加了目录。从上面

参考网址https://danielmiessler.com/blog/git-modified-untracked/#gs.W0C7X6U

于 2017-09-03T22:29:10.717 回答
6

指出我必须从 Chris Johansen 与 OP 的聊天中挖掘出的内容(链接自对答案的回复):

git add vendor/plugins/open_flash_chart_2# 将添加 gitlink,内容将保持不被跟踪

git add vendor/plugins/open_flash_chart_2/# 注意斜线!!!!

第二种形式会在不使用gitlink的情况下添加,内容是可追踪的。.git 目录被方便地自动忽略。谢谢克里斯!

于 2013-08-23T02:03:12.500 回答
5

我一直使用彼得拉达建议的技巧,被称为“假子模块”:

http://debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb

它在几个场景中非常有用(pe 我用它来将我所有的 Emacs 配置保存在一个存储库中,包括 elpa/el-get 包目录中所有 git 存储库的当前 HEAD,所以我可以轻松地回滚/转发到一个已知的某些更新破坏某些东西时的工作版本)。

于 2013-08-29T11:20:20.660 回答
4

我通过从我的子文件夹中删除 .git 文件解决了这个问题。

  1. 首先从您的子文件夹中删除 .git 文件
  2. 然后通过运行此代码git rm -rf --cached your_subfolder_name从 git 中删除您的子文件夹
  3. 然后再次通过git add 添加您的文件夹。命令
于 2020-07-20T20:14:05.177 回答
3

http://progit.org/book/ch6-6.html

我认为你应该阅读这篇文章来了解一些关于子模块的知识。写的很好,看完也不会花太多时间。

于 2010-11-12T03:08:15.800 回答
3

我在一个包含许多子模块的大项目中遇到了同样的问题。根据Chris Johnsen hereVonC here的回答,我构建了一个简短的 bash 脚本,它遍历所有现有的 gitlink 条目并将它们添加为适当的子模块。

#!/bin/bash

# Read all submodules in current git
MODULES=`git ls-files --stage | grep 160000`

# Iterate through every submodule path
while read -r MOD; do
  # extract submodule path (split line at whitespace and take string with index 3)
  ARRIN=(${MOD})
  MODPATH=${ARRIN[3]}

  # grep module url from .git file in submodule path
  MODURL=`grep "url = " $MODPATH/.git/config`
  MODURL=${MODURL##*=}

  # echo path and url for information
  echo $MODPATH
  echo $MODURL

  # remove existing entry in submodule index
  git rm --cached $MODPATH
  # add new entry in submodule index
  git submodule add $MODURL $MODPATH
done <<< "$MODULES"

这为我修复了它,我希望它有帮助。

于 2015-04-08T12:05:12.043 回答
2

这对我来说很好:

git update-index --skip-worktree

如果它不适用于路径名,请尝试使用文件名。让我知道这是否也对您有用。

再见!

于 2018-09-07T15:11:23.767 回答
1

有同样的问题,但在这个讨论中没有解决。

我也遇到了线程打开中描述的子模块问题。

% git status          
# On branch master
# Changes not staged for commit:
#   modified:   bundle/taglist (untracked content)

看着差异,我认出了附加到哈希的 -dirty:再次阅读文档,为我解决了问题。 http://web.mit.edu/jhawk/mnt/spo/git/git-doc/user-manual.html 查看“子模块的陷阱”部分

原因是,子模块中有更改或未跟踪的内容。我首先必须进入子模块目录,执行“git add”+“git commit”来获取子模块中跟踪的所有内容。

Then "git status" on the master stated
% git commit
# On branch master
# Changes not staged for commit:
#   modified:   bundle/taglist (new commits)

现在这个来自子模块的新 HEAD 可以提交给主模块。

于 2012-08-17T15:08:27.510 回答
1

我最近在从事合同项目(被视为机密)时遇到了这个问题。我必须在其中运行代码的系统没有互联网访问权限,当然出于安全目的,因此使用 composer 和 npm 安装依赖项变得非常痛苦。

在与我的同事深思熟虑之后,我们决定只使用它并复制粘贴我们的依赖项,而不是执行 composer install 或 npm install。

这导致我们不在 gitignore 中添加供应商和 npm_modules。这是我遇到这个问题的时候。

Changed but not updated:
modified:   vendor/plugins/open_flash_chart_2 (modified content, untracked content)

我用谷歌搜索了一下,在 SO 上发现了这个有用的线程。在 Git 方面不太专业,在处理它时有点陶醉,我只是在 vendor 文件夹中搜索了所有子模块

find . -name ".git"

这给了我一些有 git 的 4-5 个依赖项。我删除了所有这些 .git 文件夹,瞧,它起作用了。我知道这是 hack,而且不是一个非常令人讨厌的。SO之神,请原谅我!下次我保证阅读 gitlinks 并服从强大的 Linus Tovalds。

于 2016-02-08T19:14:32.013 回答
1

这个问题已经得到回答,但我想我会在收到这些消息时添加我发现的内容。

我有一个名为的存储库playground,其中包含许多沙盒应用程序。我通过克隆教程的存储库将教程中的两个新应用程序添加到playground目录中。结果是新应用程序的 git 内容指向教程的存储库而不是我的存储库。.git解决方案是从每个应用程序的目录中删除目录,mv在目录之外删除应用程序的playground目录,然后将mv它们返回并运行git add .. 之后它起作用了。

于 2017-11-13T18:50:53.987 回答
0

首先进入目录vendor/plugins/open_flash_chart_2DELETE


然后 :

git rm --cached vendor/plugins/open_flash_chart_2  
git add .  
git commit -m "Message"  
git push -u origin master  

git status  

输出

在分支 master
你的分支是最新的'origin/master'。
没有什么可提交的,工作目录干净

于 2018-08-05T11:57:09.397 回答
0

在我的情况下,应该添加有问题的模块/,而路径中没有前导斜杠。

错误的:

[submodule "/sources/meta-security"]
        path = /sources/meta-security
        url = git@gitlab.com:yocto/meta-security.git

正确的:

[submodule "sources/meta-security"]
        path = sources/meta-security
        url = git@gitlab.com:yocto/meta-security.git

更改后,以下命令解决了该问题:

git submodule update --init
于 2021-10-04T18:59:46.130 回答