37

使用 git 子模块时遇到问题。

每当我从上游存储库收到新的子模块引用时,执行git submodule update都会给出以下结果:

fatal: reference is not a tree: dd208d46ecdd1ac0d2b2594a610fe4c9150fece1
Unable to checkout 'dd208d46ecdd1ac0d2b2594a610fe4c9150fece1' in submodule path 'submodule/path'

需要注意的是,子模块有几个遥控器,其中上游遥控器应该用于更新子模块引用树。我猜我的问题在那里,但我不确定。

我的设置如下:

项目

遥控器:

  1. origin(我的 git 叉子)
  2. upstream(项目回购)

子模块“模块”,有遥控器:

  1. origin(我的 git 叉子)
  2. upstream(项目回购)

有谁知道是什么导致了我的问题?

4

8 回答 8

39

这样做时git submodule update,git 会尝试检查保存在超级项目中的提交/树(在您的示例中,具有提交 id 的那个dd208d4...

我认为您收到错误是因为在子模块中不存在这样的对象。你必须确保它在那里。通常这意味着您必须先从远程获取/拉取它。

可能你必须

git submodule foreach git fetch
git submodule update

或许

git fetch --recurse-submodules

假设子模块已配置,以便它可以从远程获取丢失的提交origin。最后,必须知道,你可以从哪里获取丢失的提交并且你必须得到它。

您可以dd208d4...通过执行以下操作来检查是否有:

cd ./module
git log dd208d46ecdd1ac0d2b2594a610fe4c9150fece1
git cat-file -p dd208d46ecdd1ac0d2b2594a610fe4c9150fece1
git ls-tree dd208d46ecdd1ac0d2b2594a610fe4c9150fece1

这种问题的一个可能原因是,从超级模块发布新提交的人没有从子模块发布必要的提交。他必须首先从子模块发布提交。

于 2013-02-08T16:19:12.210 回答
7

确保子模块被推送

cd submodule-dir
git push

就我而言,我有:

  • 致力于子模块
  • 不推
  • 使用更新的子模块提交给父级
  • 推了父母

所以难怪找不到。

然后,如果您使用的是 GitHub 等 Web 界面,您还可以转到子模块存储库网页,并仔细检查您需要的提交是否显示在那里。

push.recurseSubmodules on-demand

可以通过以下方式进一步自动化推送:

git push --recurse-submodules=on-demand

它还根据需要推送子模块,或者从 2.7 开始:

git config push.recurseSubmodules on-demand
git push
于 2014-08-22T12:16:48.010 回答
1

我遇到了同样的问题,我解决了为父项目添加新提交并推送所有从您的模块检查子项目提交和提交

于 2014-08-29T13:26:35.943 回答
0

我的问题是,在cat .gitmodules我的回购中,我为子模块的回购指向了错误的遥控器(我最初用原始遥控器克隆了它,但后来切换到它的一个分支;gitmodules文件从未更新以反映更改) .

于 2016-09-27T16:38:18.013 回答
0

我的问题是我在其 build.gradle 文件中的子模块中有未提交的更改(我认为这些更改是自动更改的)。他们出现在git diff. 我只是git checkout .将子模块 repos 重置为没有更改,然后git submodule update工作。

于 2017-03-08T18:02:55.923 回答
0

当我忘记在我的一个子模块中推送更改时才看到这个问题

确保推送更改

于 2017-09-05T19:32:12.463 回答
0

另一种方法可能是,没有命令行 git 选项,而是手动执行此操作。这种情况主要发生在子模块路径已被移动/替换(但不正确)时,因此仍指向本地结帐存储库中的旧引用。

1)找到存储库和子模块

ls -la .git/modules
   rm -f .git/modules/<module-with-issue>

2) 移除旧的本地子模块配置

 gedit .git/config

(此处删除子模块 url 条目)

它看起来像这样;

 *[submodule "module-with-issue"]
       url = ...*

3) 现在,重新获取和更新子模块 git fetch git submodule update --recursive --init

注意: 在尝试子模块更新之前,可能还必须删除存储库中本地签出的子模块文件夹。

于 2018-08-21T05:00:08.707 回答
0

git rm --cached <submodule-directory>在 gitlab 上添加对我有帮助:

.prepare_deploy: &prepare_deploy
  before_script:
    - bundle install -j $(nproc) --path vendor
    - which ssh-agent || (apt-get update -y && apt-get install openssh-client -y)
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - eval $(ssh-agent -s)
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - (echo "$SSH_PRIVATE_KEY" | base64 --decode) > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - git rm --cached <submodule-directory>
    - git submodule sync --recursive
    - git submodule update --init --recursive
于 2019-03-27T08:31:11.833 回答