拉取请求流程


你一直在自己的分支上开发一项功能,现在已准备好。项目是共享的:其他人也会提交代码,所以你不会直接推送到 main 并冒险。你希望你的更改被审核、讨论(如有必要),并以团队其他成员能看到的方式合并。从你机器上的分支到代码合并到 main 的整个路径就是拉取请求流程,这几乎是 GitHub 上每个团队获取更改的方式。其中 Git 部分只使用前面章节中的命令:分支、提交和推送:
$ git switch -c add-five-day-forecast
Switched to a new branch 'add-five-day-forecast'
$ git add src/forecast.js
$ git commit -m "Add five-day forecast panel"
$ git push -u origin add-five-day-forecast
Branch 'add-five-day-forecast' set up to track 'origin/add-five-day-forecast'.这个推送将你的分支发送到 GitHub。还没有合并任何东西,甚至还没有提议进行审核。下一步,打开拉取请求,是在 GitHub 网站上进行的。
打开拉取请求时发生的事情
在 GitHub 上,进行上述推送后,你通常会看到一个横幅,提供将你的新分支与 main 进行比较的选项。点击它,写下标题和简短描述说明了什么以及为什么改变,然后打开它创建的页面。那个页面就是一个**拉取请求**,通常缩写为 PR:一个将一个分支合并到另一个分支的请求,并附有一个持续的对话。
拉取请求提议进行一次合并并等待批准。有人(可能是你,也可能是队友)阅读这个更改,留下评论,只有当它看起来合适时才合并它。在此之前,你的分支和 main 保持完全不变。
Fork vs 分支
当你对存储库有写入权限时(这是你自己团队项目的常见情况),从分支打开拉取请求是可行的。对你无法写入的项目做出贡献需要额外的一步:一个**fork**,即你在自己的 GitHub 账户下的存储库副本。
你在你的 fork 中分支和提交的方式完全相同,就像在你拥有的项目中一样,推送到你的 fork,然后从你的 fork 分支打开拉取请求回到原始存储库。GitHub 在两个存储库之间进行比较的方式与它在一个存储库内比较两个分支的方式相同,所以审核和合并流程看起来是相同的。
通过审核获得你的拉取请求
打开 PR 后,它就成为关于 diff 的持续对话。审核者阅读更改,在特定行留下评论,然后批准或请求更改。当请求更改时,继续提交和推送到同一分支:每次推送都会更新同一个 PR,而不是创建一个新的。一旦审核者批准并且所有必需的检查通过,PR 就可以合并了。
为什么拉取请求不会合并
有时 PR 上的合并按钮呈灰色,GitHub 显示一条消息来代替它:"This branch has conflicts that must be resolved"(此分支有必须解决的冲突)或"This branch is out of date with the base branch"(此分支与基础分支不同步)。两条消息都描述了一个正常的、可修复的状态:main 自你分支以来已经向前推进,通常是因为其他人的 PR 在此期间合并了,你的分支需要赶上才能让 GitHub 干净地合并两者。这种情况会发生在任何有多个贡献者的项目上,所以要预料到它而不是害怕它。
用相同的方式在本地修复它,就像你会将任何两个分支合并在一起的方式:
$ git switch add-five-day-forecast
$ git fetch origin
From github.com:mara-chen/weather-app
9f8e7d6..b7c9e21 main -> origin/main
$ git merge origin/main如果没有重叠,合并会自动完成,你推送,PR 更新,按钮解锁。如果两边的相同行改变了,Git 会在文件中标记冲突,你需要解决它,完全就像 Merging and conflicts 中涵盖的那样:打开文件,编辑掉冲突标记到你想要的结果,然后 git add 和 git commit 来完成合并,并再次推送。
卡住的拉取请求需要赶上或解决其冲突。
main 或与它有冲突。没有任何损坏的。切换到你的分支,获取,并将 main 合并进来,像在其他地方一样解决任何冲突,然后再次推送。 拉取请求在内部是什么
拉取请求不是 Git 对象,也没有 git 命令创建它。Git 和 GitHub 不是同一件事:Git 只知道提交、分支和其他 ref(ref 是指向提交的名称)。GitHub 在它比较的两个 ref 之上构建整个 PR 页面、评论和合并按钮:你的分支(head)和你要合并到其中的分支(base,通常是 main)。这就是为什么你在 GitHub 的网站上(或通过 GitHub 自己的命令行工具或 API)打开拉取请求,而从不使用普通 git 命令。

