有没有办法从 GitHub 上删除分支的 PR 中获取代码?
Is there a way to grab code from a PR with a deleted branch on GitHub?
在 GitHub,我通常克隆某人的分支或将其添加为远程以下载他们的更改。但是,如果 branch/fork 被完全删除,这不是一个选项。
但是,如果您单击 PR 中的 "Files changed" 选项卡,您仍然可以在 PR 中查看更改的文件,即使 fork/branch 已删除并且 PR 已关闭。
有没有办法在我的系统上本地获取包含这些更改的分支?一个想法是通过复制粘贴网站上的更改来手动重新创建所有内容,但这种方法似乎不是最优的。
是的,比较简单:
git fetch <remote-or-url> refs/pull/1234/head:refs/heads/pr1234
例如会将他们的(GitHub 的)pull-request-#1234 提交转入您的 pr1234
分支。
背景
其工作方式很简单:
Git 中的所有名称1 是 refs 或 references。也就是说,分支名称 master
实际上只是 refs/heads/master
;标签名称 v1.2
实际上只是 refs/tags/v1.2
;您的远程跟踪 origin/master
实际上只是 refs/remotes/origin/master
。 分支名称 的名称以 refs/heads/
开头。 Git 通常会去掉任何名称的前导部分,假设您知道 master
是一个分支,v1.2
是一个标签,而 origin/master
是一个远程跟踪名称。
当您 运行 git fetch
时,您的 Git 通过名称获得 他们的 提交(和其他对象)他们的 Git 显示给您的 Git 的 -and-hash-ID 对。然后它复制所需的任何提交(和其他对象),以便您的 Git 可以更新您的远程跟踪名称 and/or 将条目写入您的 Git 的 .git/FETCH_HEAD
文件等等。最后,它做了几件事:
- 按照指示更新您自己的参考文献;和
- 写入
.git/FETCH_HEAD
.
FETCH_HEAD
文件留给git pull
代码,主要是;现在 git pull
已用 C 重写,这有点像历史文物了。
关于 refs 的好处是,被分成 namespaces,您或任何人都可以发明自己的。 refs/heads/
和 refs/tags/
和 refs/remotes/
space 被采用,refs/bisect/
和 refs/replace/
以及其他一些,但是 Git Hub 能够使用 refs/pull/
,而 Git 本身不会,来存储 他们的 名字。
在此 refs/pull/
space、GitHub 中插入 PR 或问题编号(这些编号是每个存储库的,否则是存储库的全局编号),然后是 /head
用于提示提交,/merge
用于执行无人值守的自动测试 git merge
的结果。如果自动合并 失败 ,GitHub 就不会创建 merge
ref。因此,如果有编号为 1234 的 PR,则 refs/pull/1234/head
存在;如果该 PR 成功测试合并,refs/pull/1234/merge
也存在,如果不存在,则不存在。
请注意,从他们的(GitHub's)branch 名称到您的 remote-tracking 名称的转换是由你自己的 remote.origin.fetch
配置行,默认为:
+refs/heads/*:refs/remotes/origin/*
这是一个 refspec: 一对 ref,用冒号分隔,可以选择使用加号作为前缀 +
(通常用于这种特殊情况) .这匹配他们所有的 branch 名称,因为左侧或 source 模式匹配分支名称。它会导致您的 Git 将其分支名称替换为您的远程跟踪名称,因为右侧或 destination 模式将 refs/heads/
替换为 refs/remotes/origin/
(保持 *
匹配的所有内容完好无损)。
这意味着您可以添加:
+refs/pull/*/head:refs/heads/pr*
到你的 remote.origin.fetch
refspecs,在你的 .git/config
中,这样 git fetch
将自动并且几乎总是,2 创建或更新您的 pr<em>number</em>
个分支机构。但是,它可能会破坏您自己创建的任何个人 pr<em>number</em>
分支,因此请注意,如果您这样做,你必须避免命名分支 pr
-something(至少是数字,但要小心 p运行ing;见脚注 2)。
1这里的例外是HEAD
、MERGE_HEAD
、CHERRY_PICK_HEAD
等。虽然 FETCH_HEAD
有时像参考一样工作,但 FETCH_HEAD
文件特别特殊,因为它可以包含多行和一些额外的注释;其他的仅包含(并且恰好)一个哈希 ID 或一个符号引用。
2"Always" 太强了,甚至我那略微狡猾的措辞 almost almost always 也可能是:任何时候你 运行 git fetch
带有一些 refspec 参数,这将覆盖此默认值。您配置的 remote.origin.fetch
设置只有在您没有覆盖它们时才会被使用。记住它是如何与 fetch.prune
或 git fetch -p
交互的:目标中的 *
现在意味着 Git 将自动 删除 匹配的引用不是由 fetch 操作写入的。
写 pr*
而不是 pr/*
的能力取决于您的 Git 年份。在一些旧版本的 Git 中,refspecs 中类似 glob 的 *
模式只能以 "whole name component" 方式使用,例如,refs/heads/*:refs/remotes/origin/*
在所有 [=161= 中总是可行的] 版本,无论多么古老,但有时 refs/heads/a*:refs/remotes/origin/a*
不是。
在 GitHub,我通常克隆某人的分支或将其添加为远程以下载他们的更改。但是,如果 branch/fork 被完全删除,这不是一个选项。
但是,如果您单击 PR 中的 "Files changed" 选项卡,您仍然可以在 PR 中查看更改的文件,即使 fork/branch 已删除并且 PR 已关闭。
有没有办法在我的系统上本地获取包含这些更改的分支?一个想法是通过复制粘贴网站上的更改来手动重新创建所有内容,但这种方法似乎不是最优的。
是的,比较简单:
git fetch <remote-or-url> refs/pull/1234/head:refs/heads/pr1234
例如会将他们的(GitHub 的)pull-request-#1234 提交转入您的 pr1234
分支。
背景
其工作方式很简单:
Git 中的所有名称1 是 refs 或 references。也就是说,分支名称
master
实际上只是refs/heads/master
;标签名称v1.2
实际上只是refs/tags/v1.2
;您的远程跟踪origin/master
实际上只是refs/remotes/origin/master
。 分支名称 的名称以refs/heads/
开头。 Git 通常会去掉任何名称的前导部分,假设您知道master
是一个分支,v1.2
是一个标签,而origin/master
是一个远程跟踪名称。当您 运行
git fetch
时,您的 Git 通过名称获得 他们的 提交(和其他对象)他们的 Git 显示给您的 Git 的 -and-hash-ID 对。然后它复制所需的任何提交(和其他对象),以便您的 Git 可以更新您的远程跟踪名称 and/or 将条目写入您的 Git 的.git/FETCH_HEAD
文件等等。最后,它做了几件事:- 按照指示更新您自己的参考文献;和
- 写入
.git/FETCH_HEAD
.
FETCH_HEAD
文件留给git pull
代码,主要是;现在git pull
已用 C 重写,这有点像历史文物了。
关于 refs 的好处是,被分成 namespaces,您或任何人都可以发明自己的。 refs/heads/
和 refs/tags/
和 refs/remotes/
space 被采用,refs/bisect/
和 refs/replace/
以及其他一些,但是 Git Hub 能够使用 refs/pull/
,而 Git 本身不会,来存储 他们的 名字。
在此 refs/pull/
space、GitHub 中插入 PR 或问题编号(这些编号是每个存储库的,否则是存储库的全局编号),然后是 /head
用于提示提交,/merge
用于执行无人值守的自动测试 git merge
的结果。如果自动合并 失败 ,GitHub 就不会创建 merge
ref。因此,如果有编号为 1234 的 PR,则 refs/pull/1234/head
存在;如果该 PR 成功测试合并,refs/pull/1234/merge
也存在,如果不存在,则不存在。
请注意,从他们的(GitHub's)branch 名称到您的 remote-tracking 名称的转换是由你自己的 remote.origin.fetch
配置行,默认为:
+refs/heads/*:refs/remotes/origin/*
这是一个 refspec: 一对 ref,用冒号分隔,可以选择使用加号作为前缀 +
(通常用于这种特殊情况) .这匹配他们所有的 branch 名称,因为左侧或 source 模式匹配分支名称。它会导致您的 Git 将其分支名称替换为您的远程跟踪名称,因为右侧或 destination 模式将 refs/heads/
替换为 refs/remotes/origin/
(保持 *
匹配的所有内容完好无损)。
这意味着您可以添加:
+refs/pull/*/head:refs/heads/pr*
到你的 remote.origin.fetch
refspecs,在你的 .git/config
中,这样 git fetch
将自动并且几乎总是,2 创建或更新您的 pr<em>number</em>
个分支机构。但是,它可能会破坏您自己创建的任何个人 pr<em>number</em>
分支,因此请注意,如果您这样做,你必须避免命名分支 pr
-something(至少是数字,但要小心 p运行ing;见脚注 2)。
1这里的例外是HEAD
、MERGE_HEAD
、CHERRY_PICK_HEAD
等。虽然 FETCH_HEAD
有时像参考一样工作,但 FETCH_HEAD
文件特别特殊,因为它可以包含多行和一些额外的注释;其他的仅包含(并且恰好)一个哈希 ID 或一个符号引用。
2"Always" 太强了,甚至我那略微狡猾的措辞 almost almost always 也可能是:任何时候你 运行 git fetch
带有一些 refspec 参数,这将覆盖此默认值。您配置的 remote.origin.fetch
设置只有在您没有覆盖它们时才会被使用。记住它是如何与 fetch.prune
或 git fetch -p
交互的:目标中的 *
现在意味着 Git 将自动 删除 匹配的引用不是由 fetch 操作写入的。
写 pr*
而不是 pr/*
的能力取决于您的 Git 年份。在一些旧版本的 Git 中,refspecs 中类似 glob 的 *
模式只能以 "whole name component" 方式使用,例如,refs/heads/*:refs/remotes/origin/*
在所有 [=161= 中总是可行的] 版本,无论多么古老,但有时 refs/heads/a*:refs/remotes/origin/a*
不是。