git subtree pull提示工作树已修改,但git status显示没有修改。这是怎么回事?

49

如果我在我的一个代码库中这样做:

git subtree pull --prefix=frameworks/AquaticPrime --squash AquaticPrime

我得到了这个:

Working tree has modifications.  Cannot add.

如果我在同一位置执行以下操作:

git status

我得到了这个:

# On branch master
nothing to commit (working directory clean)

我不太确定这里发生了什么事情。 git status 命令表明我没有进行修改,所以我假设 git subtree pull 指的是与子树相关的不同分支中的修改,但这并不完全清楚。

有人可以提供启示吗?


3
从快速查看源代码来看,git-subtreegit diff-index HEAD --exit-code --quiet 退出“失败”,即存在更改时打印输出。如果运行 git diff-index HEAD 会发生什么? - Cascabel
1
您也可以尝试使用“-d”(调试)选项。 - Cascabel
1
当我运行 git diff-index HEAD 命令时,会出现“fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.”的错误提示。如果使用 -d debug 标志,则会得到类似的输出。因此,问题是,为什么 HEAD 会未知? - B T
2
@BT 我认为你尝试在没有任何提交的仓库中使用git子树。Git应该增强此类情况下的错误提示信息。我刚刚添加了一个随意的提交来启动仓库,之后subtree就可以正常工作了。 - Avindra Goolcharan
我收到了相同的信息,但我仍然需要拉取主分支和我的功能分支,然后将主分支合并到功能分支,然后才能从子树中拉取最近的提交。 - Jeremy Ray Brown
显示剩余3条评论
9个回答

46

我刚遇到了同样的问题。 当 git diff-index HEAD 命令返回结果时,从GIT源代码中会抛出错误,即使 git status 显示工作树是干净的。

为了避免这个错误,在我的情况下,我重新检出当前工作树的分支,一切似乎都正常了:git checkout <branch>

虽然有点混淆,但如果有人能解释为什么...


1
问题的描述很好,但我需要更多的信息来实现它...哦,你只是想在主(非子树)模块中运行“git checkout master”。太棒了! - Michael Scott Asato Cuthbert
2
git checkout 没有解决我的问题,但是 git reset 解决了。 - Qiulang

18

git reset --hard对我来说解决了问题。

来自git reset --help

--hard重置索引和工作树。自从上次提交后,工作树中已跟踪文件的任何更改都将被丢弃。


2
只有当您确定 git reset --hard 的作用时,才使用它,否则可能会丢失工作。也许 git stash save --include-untracked 是更安全的选择?(因为您可以稍后检索存储的工作) - pavol.kutaj

14

我现在已经解决了这个问题。我的问题似乎是由于该仓库是全新的,我从未提交过任何内容。一旦我向仓库提交了一个文件,我就能够摆脱这个错误。

然而,当我使用命令git subtree add C:\gitTest\repos\subA -d --prefix subA时,我遇到了新的错误:

致命错误:你希望我如何合并0棵树?

在尝试了一分钟之后,我发现它要求传递一个特定的版本。所以这个命令似乎成功了:

git subtree add C:\gitTest\repos\subA HEAD -d --prefix subA

显然,你不需要-d调试标志。


1
非常感谢您!您关于空仓库问题的观察结果也在这个有关git tfs subtree add问题的问题中得到了验证。确切的错误信息是fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.,它与空仓库中主分支上“缺少HEAD”有关。 - quetzalcoatl

2

我刚遇到了这个问题,当我:

  • 添加了一个子目录;
  • 意识到我错误地将其添加到了错误的目录中;
  • 使用rm删除它;
  • 尝试重新导入它(到正确的位置)。

虽然 puppet diff 正确地显示为无内容,但 git diff-index HEAD 将我刚刚删除的每个文件都列为“已删除”——即使我从未提交过任何东西(更不用说推送了)。

我相信,这是git中的一个bug(在这里使用的是2.7.0版本)... 无论是否存在bug,解决方法是切换到任何其他分支(使用通常的git checkout ....),然后再切回你的分支。希望这能帮助某人——即使不是最初的提问者。


0
如果您正在使用Windows,尝试使用Git Bash而不是PowerShell或cmd.exe。在我的情况下,这解决了问题。

0

我遇到了完全相同的错误。这是在我的功能分支上发生的。解决方法如下:

  1. 从功能分支远程拉取到本地
  2. 从主分支远程拉取到本地
  3. 将本地主分支合并到功能分支,提交并推送到远程
  4. 运行 `git subtree pull --prefix MySubdirection https://my/repository/url remotebranch --squash`

我不知道为什么必须获取主分支并将其合并到我的功能分支,但这解决了问题。


0
我在使用SourceTree时遇到了这个问题。问题出现在我设置子树时,我选择了一个已存在的文件夹。虽然有警告提示,但我忽略了它。重新设置子树,并输入一个尚不存在的文件夹名称解决了这个问题。

0
确保在尝试执行修改存储库的 Git 命令(如 git subtree add)之前,将所有对本地 Git 存储库进行的更改都已提交。这样可以避免由于未提交的更改而导致的任何问题。

-5

1
谢谢,我感到有点不好意思,没有给你的答案投赞成票或勾选,但事实上已经很久没用过子树了,也无法测试答案是否可行! - Sam Deane
3
我有同样的问题,去掉 "--squash" 也无法解决它。 - Bernard
2
我一开始并没有使用 squash。事实上,我甚至不知道为什么你会认为它会起作用,因为你发布的 SO 问题并没有询问我们收到的消息。 - B T

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