git - 有没有办法从 GitHub 上已删除分支的 PR 中获取代码?
问题描述
在 GitHub 上,我通常克隆某人的 fork 或将其添加为远程以下载他们的更改。但是,如果分支/分叉被完全删除,这不是一个选项。
然而,如果您在 PR 中单击“文件已更改”选项卡,您仍然可以在 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 的 name-and-hash-ID 对来获取他们的提交(和其他对象)。然后它会复制所需的任何提交(和其他对象),以便您的 Git 可以更新您的远程跟踪名称和/或将条目写入您的 Git.git/FETCH_HEAD
文件等等。最后,它做了几件事:- 按照指示更新您自己的裁判;和
- 写
.git/FETCH_HEAD
。
该FETCH_HEAD
文件主要用于git pull
代码;现在它git pull
已经被用 C 重写了,有点像历史文物。
refs 的好处是,被划分为命名空间,你或任何人都可以发明你自己的。refs/heads/
andrefs/tags/
和refs/remotes/
空格被占用,andrefs/bisect/
和refs/replace/
其他一些空格也是如此,但是 GitHub 能够使用refs/pull/
Git 本身没有的 来存储他们的名字。
在这个refs/pull/
空间中,GitHub 插入 PR 或问题编号(这些编号是每个存储库的,否则对于存储库是全局的),然后/head
是提示提交和/merge
执行无人值守的自动测试的结果git merge
。如果自动合并失败,GitHub 根本不创建merge
ref。因此,如果存在编号为 1234 的 PR,则refs/pull/1234/head
存在;如果该 PR 成功测试合并,refs/pull/1234/merge
则也存在,如果不存在,则不存在。
请注意,从他们的(GitHub 的)分支名称到您的远程跟踪名称的转换由您自己的remote.origin.fetch
配置行控制,默认为:
+refs/heads/*:refs/remotes/origin/*
这是一个refspec:一对 refs,用冒号分隔,并且可选地以加号作为前缀+
(总是用于这种特殊情况)。这匹配他们所有的分支名称,因为左侧或源模式匹配分支名称。它会导致您的 Git 用您的远程跟踪名称替换它们的分支名称,因为右侧或目标模式替换refs/heads/
为refs/remotes/origin/
(保持所有匹配的内容*
不变)。
这意味着您可以添加:
+refs/pull/*/head:refs/heads/pr*
到您的remote.origin.fetch
refspecs,在您的, 中.git/config
,这git fetch
将自动并且几乎总是2创建或更新您的分支。但是,它可能会破坏您自己创建的任何您自己的个人分支,因此请注意,如果您这样做,您必须避免命名分支-something(至少是数字的东西,但要小心修剪;见脚注 2) .prnumber
prnumber
pr
1这里的例外是HEAD
、MERGE_HEAD
、CHERRY_PICK_HEAD
等。虽然FETCH_HEAD
有时像参考一样工作,但该FETCH_HEAD
文件特别特别,因为它可以包含多行和一些额外的注释;其他仅包含(并且完全)一个哈希 ID 或一个符号引用。
2 “总是”太强了,甚至我那略显狡猾的措辞几乎总是也可能如此:任何时候你git fetch
使用一些 refspec 参数运行,这将覆盖这个默认值。remote.origin.fetch
仅当您没有覆盖它们时才使用您配置的设置。记住它是如何与fetch.prune
or交互的git fetch -p
:*
目标中的现在意味着 Git 将自动删除不是由 fetch 操作写入的匹配引用。
编写pr*
而不是,例如,的能力pr/*
取决于您的 Git 年份。在某些较旧版本的 Git 中,refspecs 中的类 glob*
模式只能以“全名组件”的方式使用,例如,refs/heads/*:refs/remotes/origin/*
在所有 Git 版本中总是可以的,无论多么古老,但有时refs/heads/a*:refs/remotes/origin/a*
不是。
推荐阅读
- java - Thymeleaf - 将变量传递给控制器
- c - c语言中的变长数组替代
- javascript - 使用动态扩展类表达式创建新元素
- java - Java Selenide - 在循环期间进行修改的 For-Looping ElementsCollection
- css - 速记模态内容不适用于 React Semantic UI 中的 HTML 标签
- python-3.x - 我正在尝试在窗口上显示鼠标位置,但无法更新窗口上的文本
- ios - Xcode 10.2 iOS Swift (+ React Native) 项目编译错误
- pug - 我如何在 pugjs 中使用 json 文件
- android - 嵌套的 RecyclerView onClick 未触发
- html - 角度 7 变化前图像闪烁