git-subtree pull 的问题

33

我们一直在尝试在项目中使用 git-subtree(使用的是git版本1.7.9.4),但遇到了一些复杂的问题。几个月前,有人用以下命令添加了子树:

git subtree add --prefix=foo git@example.com:foo.git master

现在foo已经有了实质性的变化,我们希望将这些更改合并进来,最好是压缩它们。自从导入以来,这些文件中没有任何修改。

我尝试了三件事来合并这些更改。

第一:

git subtree pull --squash -P foo git@example.com:foo.git master

哪个会抛出异常:无法合并压缩:'foo'从未添加过。

其次:

git subtree pull -P foo git@example.com:foo.git master

这个方法(有点)可行,但存在一个问题,即拉取了所有提交并且与已修改文件有冲突。

最后,我尝试了这个:

git pull --squash -s subtree git@example.com:foo.git  master

这样做可以得到我想要的结果,输出为自动合并进行良好;在请求停止提交之前停止,所有文件都显示为已修改(内容正确)。

理想情况下,我想继续使用第一版本的git-subtree并获得接近最后一个版本的输出。如果我们必须始终使用最后一个版本,那么我们就会这样做,但我有点困惑为什么最后一个版本不会产生合并冲突而中间版本会。

感谢任何帮助。

4个回答

16

我曾经遇到了同样的问题,而在我的情况下,似乎是由于最初的子树提交被合并压缩到主分支中所致。

通过查看子树源代码,我发现了这个:https://github.com/git/git/blob/master/contrib/subtree/git-subtree.sh#L224

它看起来像是在你的git日志中搜索 git-subtree-dir: foo 但找不到合适的提交。尝试使用命令 git log --grep="git-subtree-dir: foo/*\$",如果该提交存在异常,例如它是一个合并提交,那可能就是问题所在。

对我来说,只是简单地拉取而不合并已经解决了问题,除了恼人的合并冲突以外。我在一个临时分支上执行了这个操作,然后将其 git merge --squash 到另一个分支中,以避免更混乱的历史记录。当然也可以使用rebase代替。


2
我曾经遇到过同样的问题,结果发现是因为我在尝试拉取时错过了前缀选项中的子文件夹。我将此添加为评论,因为错误消息没有指示此错误,并且故障排除将我带到了这里。 - David Svensson
谢谢,这很有用。我遇到了一个相关的问题,即在将子目录添加到其中的子树后移动了子目录,这似乎会使匹配出现问题。 - Arkadiy Kukarkin
我曾经遇到过这个问题,原因是我们的stashweb策略压缩了提交。我通过找到一个子树提交并使用“git merge -s ours <commit>”将其合并到历史记录中来解决了这个问题。 - Alex Brown

3
我在使用Sourcetree 1.7.0时,每次在子树上执行拉取操作后都会遇到相同的错误信息“无法进行压缩合并:未添加'foo'”。 然而,我认为我的情况不同,因为我正在使用子目录。
Sourcetree执行以下操作:
git -c diff.mnemonicprefix=false -c core.quotepath=false subtree pull -P dir1\subdir1 --squash remote-repo master 显然,如果我们在Git Bash中再次尝试,则应该是以下命令:
git subtree pull -P "dir1\subdir1" --squash remote-repo master 但是,这样做失败了。虽然命令语法没问题,但以下命令也失败了:
git subtree pull -P dir1/subdir1 --squash remote-repo master 我找到的解决办法是在Git Bash中使用以下命令:
git subtree pull -P "dir1/subdir" --squash remote-repo master 我想这表明Git的命令行处理引擎还有一些工作要做。

2
如果当前克隆是部分克隆(例如,使用--depth=1时),也会发生这种情况。这是GitHub Actions V2的默认设置。
在GitHub Actions中,可以在检出步骤中使用fetch-depth: 0进行配置:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source
        uses: actions/checkout@v2
        with:
          ref: master
          fetch-depth: 0

1
这可能发生在主仓库和子树仓库拥有不同的提交集时。
在我的情况下,我使用git subtree pull --squash -P foo local/foo.git master 从本地仓库更新了子树,但是本地仓库的更改从未推送到远程仓库。
在此之后,当我尝试执行git pull --squash -s subtree git@example.com:foo.git master时,就开始出现错误。
只需推送子树仓库即可解决该错误。

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