更改分支时未找到 SPM 未知错误参考

问题描述 投票:0回答:7

我的项目的一些依赖项托管在私有存储库上。它在大多数情况下都有效,但有时当我用 git 更改当前分支时,我会收到此错误:

❌ git@my_private_repo.git: An unknown error occurred. reference 'refs/remotes/origin/main' not found (-1)

从那时起,就不可能编译了,我唯一的选择就是重置 SPM 缓存,这需要很多时间。

知道造成这种情况的原因以及如何解决吗?

ios xcode macos swift-package-manager
7个回答
26
投票

就像其他人回答的那样,可以通过删除项目的派生数据目录中的 Swift 包缓存以及

~/Library/Caches/org.swift.swiftpm
中的全局 Swift 包管理器缓存来解决该问题。更好的是,仅删除受影响的
remotes
目录,但查找包和文件夹可能非常耗时。

这是我快速整理的一个小脚本,它将删除全局 Swift Package Manager 缓存和项目的派生数据存储库目录中名为

remotes
的所有目录。

#!/bin/bash

if [[ $# -eq 0 ]] ; then
    echo 'Please call the script with the name of your project as it appears in the derived data directory. Case-insensitive.'
    echo 'For example: ./fix-spm-cache.sh myproject'
    exit 0
fi

# Delete all directories named "remotes" from the global Swift Package Manager cache.
cd ~/Library/Caches/org.swift.swiftpm/repositories

for i in $(find . -name "remotes" -type d); do
    echo "Deleting $i"
    rm -rf $i
done

# Find derived data directories for all projects matching the script argument, and
# delete all directories named "remotes" from source package repositories cache for those projects. 

cd ~/Library/Developer/Xcode/DerivedData/

for project in $(find . -iname "$1*" -type d -maxdepth 1); do
    for i in $(find "$project/SourcePackages/repositories" -name "remotes" -type d); do
        echo "Deleting $i"
        rm -rf $i
    done
done

如果将代码保存在名为

fix-spm-cache.sh
的文件中,则可以执行
chmod +x fix-spm-cache.sh
使该文件可执行。之后,当您在 Xcode 中遇到错误时,只需使用项目名称运行脚本即可,如
./fix-spm-cache.sh myproject

运行脚本时您可以保持 Xcode 打开。脚本执行完毕后,再次尝试解析或更新您的包。它应该可以工作,并且应该相对较快,因为我们没有删除整个缓存。

这应该可以解决本主题中提到的错误,以及 Xcode 13 中发生的臭名昭著的

SwiftPM.SPMRepositoryError error 5
,这可能是相同的错误,只是消息不同。


14
投票

我想我可能在这里找到了问题!经过大量挖掘后,似乎 Xcode 和 Swift PM 在使用 git@ 而不是 https://

的存储库上存在错误

使用 ssh,我们在缓存和派生数据中获得对远程/源/主的挂起引用。使用 https 时,情况并非如此。这是有道理的,因为我们项目中使用 ssh 的唯一部门是我们的内部部门。

我通过添加一个全新的第 3 方依赖项 [email protected]:jpsim/Yams.git 到我们的项目中进行了测试,并看到 org.swift.swiftpm 中的缓存更新不正确。

更新:10天后,这似乎一直是问题所在。然而,即使在更改引用之后,在 Xcode 不再有任何对

git@
存储库的引用之前,也需要完整的 DerivedData/SPM 缓存/Package.resolved 擦除。我已针对此错误向 Apple 提交了反馈。


11
投票

在 XCode 和 AppCode 中出现此问题后(它们没有“重置包缓存”按钮,并且在删除 DerivedData 文件夹时需要永远重新索引整个 iOS 框架),我尝试最小化需要删除的文件夹。

我最终得到以下结果: 一旦您收到错误消息

[email protected]: An unknown error occurred. reference 'refs/remotes/origin/main' not found (-1)
,您

  1. 转到您的 DerivedData 文件夹 (
    ~/Library/Developer/Xcode/DerivedData/
    )(对于 AppCode,它位于
    ~/Library/Caches/JetBrains/AppCode2022.2/DerivedData
  2. 转到以下目录,当然,与您的项目名称相匹配:
    <YourProject>-<RandomCharacters>/SourcePackages/repositories/<FailingLibraryProject>-<RandomCharacters>/refs/
  3. 删除
    remotes
    文件夹
  4. 在 XCode 中,单击文件 -> 包 -> 解析包版本
  5. 在 AppCode 中,单击“工具”->“Swift 包管理器”->“解决依赖关系”。
  6. 关闭并重新打开XCode

这就是所需要的一切——至少对我来说是这样。我想您需要对每个失败的图书馆项目重复这些步骤。 最好的事情是:无论我切换分支或依赖版本多少次,我都不需要再次执行此操作:)


3
投票

遇到同样的问题,甚至创建了具有相同内容的新存储库以查看它是否正常工作。最后我找到了一个对我有帮助的解决方案。

  1. 从项目中删除包
  2. 关闭 Xcode
  3. 清洁 SPM -
    swift package purge-cache
  4. 删除派生数据 -
    rm -rf ~/Library/Developer/Xcode/DerivedData
  5. 打开项目并再次添加包。

附注

purge-cache
不删除
DerivedData
不起作用,但可能只需要删除
DerivedData
即可解决此问题。无法重新检查,因为我无法再重现此问题。

UPD: 不需要步骤#3。


3
投票

今天似乎对我有用的东西,只需要几秒钟,并且不会删除派生数据文件夹:

  • 暂时删除导致 Swift 包中出现问题的依赖项
  • 关闭 Xcode
  • 签出 Package.resolved 以取消其更改
  • 重新打开 Xcode

几秒钟后,一切似乎又恢复正常了。


0
投票

我制作了一个 python 脚本来解决这个问题。 这个想法是获取最新的提交哈希并将其写入 Package.resolved,然后为您解析PackageDependency。

您可以获取下面的脚本,或者从这里

下载
# Sometimes Xcode cannot resolve SPM(File -> Packages -> Resolve Package versions) if the dependency url is ssh
# This script is a workaround to resolve package versions.
# Usage:
#     python spmResolve.py
# or
#     python3 spmResolve.py
import os.path
import subprocess
import glob
import json


def main():
    package_file = "xcshareddata/swiftpm/Package.resolved"
    xcodeproj = glob.glob('*.xcodeproj')
    xcworkspace = glob.glob('*.xcworkspace')
    spmproj = glob.glob('Package.resolved')
    package_resolved = ""
    if xcodeproj:
        package_resolved = xcodeproj[0] + f"/project.xcworkspace/{package_file}"
    elif xcworkspace:
        package_resolved = xcworkspace[0] + f"/{package_file}"
    elif spmproj:
        package_resolved = spmproj[0]
    else:
        print(f"😱 Cannot find *.xcodeproj, *.xcworkspace or Package.resolved file")
        exit(-1)

    update_package_resolved(package_resolved)


def update_package_resolved(package_resolved):
    if not os.path.exists(package_resolved):
        print(f"😱 Package.resolved file doesn't exit: {package_resolved}")
        exit(-1)

    print(f"Found: {package_resolved}")
    f = open(package_resolved)
    content = json.load(f)
    f.close()
    for pin in content["pins"]:
        url = pin["location"]
        if "branch" in pin["state"]:
            branch = pin["state"]["branch"]
            commit_hash = get_git_revision_hash(url, branch)
            print(f"{url}, {branch}, {commit_hash}")
            pin["state"]["revision"] = commit_hash
        elif "version" in pin["state"]:
            version = pin["state"]["version"]
            commit_hash = get_git_revision_by_tag(url, version)
            print(f"{url}, {version}, {commit_hash}")
            pin["state"]["revision"] = commit_hash

    with open(package_resolved, "w") as output:
        json.dump(content,  output, indent=4)

    # resolve SPM
    subprocess.run(['xcodebuild', '-resolvePackageDependencies'])
    print('🎉 Well done')


def get_git_revision_hash(url, branch) -> str:
    command = f'git ls-remote {url} refs/heads/{branch} | cut -f 1'
    return get_git_command_output(command)


def get_git_revision_by_tag(url, version) -> str:
    command = f'git ls-remote {url} -t {version} | cut -f 1'
    return get_git_command_output(command)


def get_git_command_output(command) -> str:
    return subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True).decode('ascii').rstrip()


if __name__ == '__main__':
    main()


将脚本与

*.xcodeproj
*.xcworkspace
一起放入您的 xcode 项目中。 然后运行

python spmResolve.py

python3 spmResolve.py

如果你没有Python:

brew install python

0
投票

我有同样的错误,但通过 https 添加了存储库。我刚刚删除了

~/Library/Caches/org.swift.swiftpm
处的缓存,看起来它有效。重置软件包,清除派生数据没有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.