如何列出所有远程引用?

29
最近我在GitHub上创建了一个PR,但是一些测试失败了。而且在本地更多的测试也没有通过。所以我试图找出问题所在。
我发现的问题是Travis在测试的时候使用的是一个我没有的其他提交。这个引用是refs/pull/81/merge。所以,有人应该已经将我的分支合并到了主分支,并创建了相应的引用。是GitHub还是Travis做的呢?
另外一个问题是,我能列出GitHub仓库的所有引用吗?

根据标签维基,'refs' 标签应该用于微软的REsilient FileSystem (REFS)。 - undefined
1
@ryanwebjackson 已修复 - undefined
3个回答

23

关于Travis本身我不了解,但是GitHub确实创建了这些refs/pull/number/merge引用。特别是基于观察 - 文件似乎有点简略,而且我只是GitHub的一位有些随意的用户 - 当您在GitHub上单击“新拉取请求”时,GitHub会:

  • 创建一个名为refs/pull/number/head的引用,以保存您要求其他人为您合并的提交的ID;
  • 尝试进行自动合并和提交(使用git merge),如果成功,则创建第二个名为refs/pull/number/merge的引用。

请注意,此自动创建的合并提交不属于任何分支,它仅具有相同的拉取请求编号,并且引用名称从拉取请求本身很明显(只需将head替换为merge)。 我认为 - 但没有手动测试 - 此合并的第一个父提交是您请求他人在他们执行相同合并时所在的分支的最新提交,即在幕后创建此refs/pull/number/merge引用的代码是(或非常接近于):

commithash=...                         # the commit ID for the pull-request
mergeinto=$(git rev-parse $branchname) # the branch we are to merge into
prnum=...                              # get next pull request number

# create the pull request itself
git update-ref refs/pull/$prnum/pull $commithash

# create the merge ref, if the merge succeeds
git checkout $mergeinto
if git merge -m "..." refs/pull/$prnum/pull; then
    # merge succeeded: create the merge ref
    git update-ref refs/pull/$prnum/merge HEAD
else
    # automatic merge failed, discard it
    git merge --abort
fi

(这段代码序列会对索引进行操作,而且会使 HEAD 处于分离状态,因此必须在仓库被锁定并进行后期清理或使用临时工作树的情况下完成;由于各种原因,实际的代码序列可能不同。)

因此:

所以,有人声称将我的分支合并到主分支,并创建了相应的引用。是 GitHub 还是 Travis 做的?

鉴于 GitHub 奥卡姆剃刀原则建议无需调用 Travis。 :-)

另一个问题是,我能列出 GitHub 仓库中的所有引用吗?

只要您有访问权限:

$ git ls-remote

(假设远程是一个GitHub URL),将显示所有公开的引用。我没有看到通过Web界面进行此操作的方法,也没有在我的(轻微)浏览GitHub API文档时找到。


我明白了,git ls-remote 命令必须在远程仓库中运行,或者可以在派生的仓库中使用 git ls-remote REMOTE_NAME 命令。 - x-yuri
2
@x-yuri:更准确地说,git ls-remote会查找当前分支的“remote”设置,除非您给它一个参数。该参数可以是远程名称(如“origin”或“upstream”),在这种情况下,git ls-remote将从中查找URL,或者可能是URL。一旦Git获得了URL,它就会调用通常的git fetch操作的第一部分,请求从其他Git获取所有公共引用的列表。 - torek

21

如果你只想获取存储库中所有引用的列表,可以运行以下命令:

git show-ref

这将打印位于.git/refs/*下的每个引用的<SHA> <NAME>


并非所有的引用都在.git/refs/*中 - 有些可能在.git/packed-refs中。 - Thomas Guyot-Sionnest
3
这不是 OP 所要求的 - 他们要求远程引用;而不是本地存储库上的引用。 - ryanwebjackson

8
一条回答提到了git ls-remote - 虽然这通常适用于我的用例,但当服务器管理员清理我的过期远程存储库时,我需要列出git 认为 远程仓库的内容列表,并想使用本地git克隆来恢复它们。

为了列出所有已知的远程引用,我曾经使用ls .git/refs/remotes/<name>/ - 结果在某些情况下,这是不够的,例如在git-p4存储库中,我的一个远程引用仅在.git/packed-refs 中列出。

使用git branch -r可以解决问题,但输出不容易解析,还需要使用grep筛选所需的远程引用。

经过一番深入挖掘,我最终使用了git for-each-ref:

git for-each-ref --format="%(refname)" refs/remotes/<name>/

注意:git show-ref命令也可以列出引用,但是模式锚定在完整引用名称的末尾,只匹配完整组件,因此只有在您知道要使用的分支名称或列出所有引用并grep它们时才有用。我想要的是适合在一行中使用的整洁内容。

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