如何 Rebase 和更新 Pull 请求

介绍

当您致力于为像您这样的最终用户提供更好的软件时,为开源项目做出贡献是一种有益的体验。提交拉取请求后,为项目做出贡献的过程可能需要在接受之前对代码进行一些重新定位和返工,然后对您的分支进行全面清理。

本教程将指导您完成向开源软件项目提交拉取请求后可能需要采取的一些后续步骤。

先决条件

本教程将引导您完成在发出拉取请求后将执行的步骤,因此您应该已经安装了 Git,并且已经或正在考虑创建拉取请求。

截至 2020 年 11 月,GitHub 删除了基于密码的身份验证。因此,您需要创建个人访问令牌或添加SSH 公钥信息,以便通过命令行访问 GitHub 存储库。

Rebase 代码和清理注释

当您为开源做出贡献时,您可能会发现您的分支或拉取请求与上游代码之间存在冲突。您可能会在 shell 中收到这样的错误:

OutputCONFLICT (content): Merge conflict in your-file.py
Automatic merge failed; fix conflicts and then commit the result.

或者通过 GitHub 的网站在您的拉取请求中像这样:

如何 Rebase 和更新 Pull 请求插图

如果维护人员有一段时间没有响应您的拉取请求,或者有很多人同时为项目做出贡献,则可能会发生这种情况。当发生这种情况并且您仍然想要合并您的拉取请求时,您将不得不解决冲突并重新设置您的代码。

一个repository可以让我们通过改变承诺,他们是基于走动分支机构。通过这种方式,我们可以根据主分支最近的提交来重新设置我们的代码。Rebase 应该小心完成,你应该确保在整个过程中使用正确的提交和正确的分支。我们还会去使用过的git reflog命令之下的情况下,你做出了错误。

正如我们在拉取请求教程中所做的那样,我们将进入代码目录:

cd repository

接下来,您希望通过使用以下git checkout命令导航到正确的分支来确保您位于正确的分支中:

git checkout new-branch

然后,运行git fetch代码的最新上游版本:

git fetch origin

获取项目的上游版本后,您可以通过压缩或改写提交消息来清理您的评论,以使项目维护人员更容易理解它们。如果你没有做很多小的提交,这可能没有必要。

要开始此过程,您将执行交互式变基。一个互动变基可用于编辑先前提交的消息,多次提交合并成一个,或删除或恢复是没有必要不再提交。为此,我们需要能够通过数字或引用分支基础的字符串来引用我们所做的提交。

要找出我们所做的提交次数,我们可以使用以下命令检查已对项目进行的提交总数:

git log

这将为您提供与此类似的输出:

Outputcommit 46f196203a16b448bf86e0473246eda1d46d1273
Author: username-2 <email-2>
Date:   Mon Dec 14 07:32:45 2015 -0400

    Commit details

commit 66e506853b0366c87f4834bb6b39d941cd034fe3
Author: username1 <email-1>
Date:   Fri Nov 27 20:24:45 2015 -0500

    Commit details

日志显示对给定项目的存储库所做的所有提交,因此您的提交将与其他人的提交一起列出。对于具有多个作者大量提交历史的项目,您需要在命令中将自己指定为作者:

git log --author=your-username

通过指定此参数,您应该能够计算您所做的提交。如果您在多个分支上工作,您可以添加到命令的末尾以按分支进行限制。--branches[=]

现在,如果您知道在要变基的分支上所做的提交数量,则可以git rebase像这样运行命令:

git rebase -i HEAD~x

这里,-i指的是交互的 rebase,HEAD指的是来自主分支的最新提交。这x将是您从最初获取分支以来对分支所做的提交次数。

但是,如果您不知道您在分支上进行了多少次提交,则需要找到哪个提交是您的分支的基础,您可以通过运行以下命令来执行此操作:

git merge-base new-branch main

此命令将返回一个称为提交哈希的长字符串,如下所示:

Output66e506853b0366c87f4834bb6b39d341cd094fe9

我们将使用这个提交哈希传递给git rebase命令:

git rebase -i 66e506853b0366c87f4834bb6b39d341cd094fe9

对于上述任一命令,您的命令行文本编辑器将打开一个包含分支中所有提交列表的文件,您现在可以选择是压缩提交还是改写它们。

Squash 提交

当我们压缩提交消息时,我们将几个较小的提交压缩或组合成一个较大的提交。

在每次提交之前,您会看到“pick”一词,因此如果您有两次提交,您的文件将与此类似:

GNU nano 2.0.6 文件:...username/repository/.git/rebase-merge/git-rebase-todo

pick a1f29a6 Adding a new feature
pick 79c0e80 Here is another new feature

# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

现在,对于文件中除第一行之外的每一行,您应该将“pick”一词替换为“squash”以合并提交:

GNU nano 2.0.6 文件:...username/repository/.git/rebase-merge/git-rebase-todo

pick a1f29a6 Adding a new feature
squash 79c0e80 Here is another new feature

此时,您可以保存并关闭该文件,这将打开一个新文件,该文件组合了所有提交的所有提交消息。您可以根据需要改写提交消息,然后保存并关闭文件。

关闭文件后,您将收到反馈:

OutputSuccessfully rebased and updated refs/heads/new-branch.

您现在已经通过将所有提交合并为一个提交。

改写提交

当您注意到一个错字,或者您意识到您没有为每个提交使用并行语言时,重新编写提交消息非常有用。

使用git rebase -i命令执行上述交互式 rebase 后,您将打开一个文件,如下所示:

GNU nano 2.0.6 文件:...username/repository/.git/rebase-merge/git-rebase-todo

pick a1f29a6 Adding a new feature
pick 79c0e80 Here is another new feature

# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

现在,对于您要改写的每个提交,将“pick”一词替换为“改写”:

GNU nano 2.0.6 文件:...username/repository/.git/rebase-merge/git-rebase-todo

pick a1f29a6 Adding a new feature
reword 79c0e80 Adding a second new feature

# Rebase 66e5068..79c0e80 onto 66e5068 (2 command(s))

保存并关闭文件后,终端编辑器中将出现一个新的文本文件,显示提交消息的修改后的措辞。如果您想再次编辑文件,可以在保存和关闭文件之前进行。这样做可以确保您的提交消息有用且统一。

完成 Rebase

一旦您对所做的提交数量和相关提交消息感到满意,您应该在项目上游代码的最新版本之上完成分支的变基。为此,您应该从存储库的目录中运行此命令:

git rebase origin/main

此时,Git 将开始将您的提交重放到最新版本的 main 上。如果发生这种情况时遇到冲突,Git 将暂停以提示您在继续之前解决冲突。如果没有任何问题需要解决,您的输出将说明以下内容:

OutputCurrent branch new-branch is up to date.

解决冲突后,您将运行:

git rebase --continue

此命令将向 Git 指示它现在可以继续重放您的提交。

如果您之前通过使用该squash命令合并提交,则只需解决一次冲突。

使用 Force-Push 更新拉取请求

执行 rebase 后,分支的历史记录会更改,并且您无法再使用该git push命令,因为直接路径已被修改。

我们将不得不使用--forceor-f标志来强制推送更改,通知 Git 你完全了解你正在推送的内容。

让我们首先通过配置来确保我们的push.defaultis simple,这是 Git 2.0+ 中的默认值:

git config --global push.default simple

此时,我们应该通过检查我们正在处理的分支来确保我们在正确的分支上:

git checkout new-branch
OutputAlready on 'new-branch'
. . .

现在我们可以执行强制推送:

git push -f

现在,您应该会收到更新的反馈以及这是forced update. 您的拉取请求现已更新。

恢复丢失的提交

如果在某个时候你丢弃了一个你真的想集成到更大项目中的提交,你应该能够使用 Git 来恢复你可能意外丢弃的提交。

我们将使用该git reflog命令来查找丢失的提交,然后从该提交创建一个新分支。

Reflog引用日志的缩写,它记录了本地存储库中上次更新分支和其他引用的提示的时间。

从我们正在工作的代码存储库的本地目录中,我们将运行以下命令:

git reflog

运行此命令后,您将收到如下所示的输出:

Output46f1962 HEAD@{0}: checkout: moving from branch-1 to new-branch
9370d03 HEAD@{1}: commit: code cleanups
a1f29a6 HEAD@{2}: commit: brand new feature 
38f2fc2 HEAD@{3}: commit: remove testing methods 
. . .

您的提交消息将让您知道哪些提交是您留下的,并且相关字符串将位于终端窗口左侧的信息之前。code>HEAD@{x}

现在您可以获取该信息并从相关提交创建一个新分支:

git checkout -b new-new-branch a1f29a6

在上面的示例中,我们从上面显示的第三个提交创建了一个新分支,该分支推出了“全新功能”,由字符串 表示a1f29a6

根据您从这里需要执行的操作,您可以按照本教程中关于 pull requests的步骤设置您的分支,或者返回到当前教程顶部以完成重新设置新分支的工作。

注意:如果您最近运行该git gc命令来清理不必要的文件并优化本地存储库,您可能无法恢复丢失的提交。

在代码审查中期待什么

当您提交拉取请求时,您正在与一个更大的项目进行对话。提交拉取请求是在邀请其他人谈论您的工作,就像您自己正在谈论和参与更大的项目一样。为了让您进行成功的对话,重要的是您能够通过提交消息传达您提出拉取请求的原因,因此最好尽可能准确和清晰。

拉取请求审查可能会很长而且很详细,具体取决于项目。最好把这个过程看作是一种学习经验,是你改进代码并使拉取请求更好、更符合软件项目需求的好方法。审查应该允许您通过维护者的建议和指导自己进行更改。

拉取请求将记录审阅者的笔记以及你们一起进行的任何更新和讨论。在接受拉取请求之前,您可能需要在整个过程中进行几次额外的提交。这是完全正常的,并为您作为团队的一部分进行修订提供了一个很好的机会。

您的拉取请求将继续通过 Git 维护,并在整个过程中自动更新,只要您不断向同一分支添加提交并将其推送到您的分支。

尽管您将代码放到更大的世界中以供同行审查,但您永远不应觉得审查是个人化的,因此请务必阅读相关CONTRIBUTION.md文件或行为准则。确保您的提交符合项目指定的指导方针很重要,但如果您开始感到不舒服,那么您正在从事的项目可能不值得您做出贡献。开源社区中有许多欢迎空间,虽然您可以期望以批判的眼光看待您的代码,但您收到的所有反馈都应该是专业和礼貌的。

拉取请求接受并删除您的分支

如果您的拉取请求已被接受,则您已成功为开源软件项目做出了贡献!

此时,您需要通过本地存储库将所做的更改拉回 fork。这是您在完成同步 fork的过程时已经完成的操作。您可以在终端窗口中使用以下命令执行此操作:

git checkout main
git pull --rebase origin main
git push -f origin main

现在,您应该通过删除您在两个地方创建的分支来清理本地和远程分支,因为它们不再需要。首先,让我们删除本地分支:

git branch -d new-branch

-d添加到git branch命令的标志将删除您传递给命令的分支。在上面的例子中,它被称为新分支.

接下来,我们将删除远程分支:

git push origin --delete new-branch

删除分支后,您已经清理了存储库,您的更改现在位于主存储库中。您应该记住,由于您通过拉取请求所做的更改现在是主存储库的一部分,因此下载公共版本的普通最终用户可能无法使用它们。一般而言,软件维护人员会将多个新功能和修复程序捆绑到一个公共版本中。

Z2ER大部分下载资源收集于网络,只做学习和交流使用,版权归原作者所有,请在下载后24小时之内自觉删除,若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,与Z2ER无关。本站发布的内容若侵犯到您的权益,请联系z2er@z2er.com删除,将及时处理!
Z2ER » 如何 Rebase 和更新 Pull 请求