如何在不使用合并提交或命令行的情况下使 GitHub fork 保持最新?

21
贡献到存储库的正常GitHub流程是创建上游的分叉,克隆本地副本进行更改,然后将其推回您的分叉并创建PR以将更改合并到上游。但如果此后上游发生更改,如何更新您的分叉,而不创建合并提交(也不使用git CLI)?我已经知道如何以创建合并提交的方式或依赖于git命令行界面来完成此操作。这个问题特别涉及只使用GitHub.com网站或GitHub Desktop应用程序的情况(没有CLI)。由于这是一个非常常见的工作流程,因此似乎应该有一些简单的方法来使用GitHub GUI进行操作。再次强调:任何使用CLI或创建合并提交的答案(例如这种方法)都不会回答这个问题,因为我明确寻求非CLI解决方案。

我知道用CLI回答这个问题会很诱人。之所以有赏金是因为我明确不想要使用CLI工具的答案。请注意,git没有被标记:这是有意的。此外,我知道你可以通过GitHub.com网站执行许多步骤来从上游拉取,但这会创建一个合并提交,这也是我明确不想要的另一件事情。 - brentonstrine
3个回答

13
仅使用GitHub Web UI而不涉及合并提交或使用CLI,是不可能的。因为这需要在PR分支上执行“变基”操作以覆盖“upstream/master”。简而言之,不行。但如果你真的想尝试一下,可以通过GitHub Web UI进行变基操作,自2016年9月起... 如果您是原始存储库的维护者,并希望集成PR分支,或者重放的提交都没有引入冲突,则可以这样做。

https://github.blog/wp-content/uploads/2016/09/a03fa9b6-7f35-11e6-8fa0-e16b2fede8ca.gif?resize=788%2C423

这与GitHub桌面版不同,自2019年6月5日起支持变基。但那是Git CLI的前端,就像其他工具一样提供该功能。例如GitKraken和交互式变基

因此,一个复杂的解决办法是:

  • 获取并推送upstream/master到你自己fork的master分支(这是一个CLI操作,但稍后会有更多介绍)
  • 将当前PR的基本分支更改master(因此在同一存储库中的PR:您自己的fork),前提是您还没有推送到master
    意思是:您的fork中的master代表了更新的upstream/master,其中upstream是您派生的原始存储库。
  • 由于您是该存储库(您的fork)的所有者,因此GitHub可以向您显示是否可以将该分支变基到PR的基本分支(master),但仅当没有冲突时才能如此。
  • 最后,再次更改基本分支,以便为PR指定目标<originalRepo>/master

第一步通常通过命令行完成,但是...也可能有一些技巧可以通过Web UI完成(在GitHub的Web UI上同步原始版本库和fork),请参见Bruno Skvorc的“快速提示:通过GitHub的Web UI同步Fork和原始版本库”。

简而言之,它包括:

  • 从当前的master(在您分叉原始存储库时,它将位于upstream/master)创建一个新的分支creating a new branch

https://help.github.com/assets/images/help/branch/branch-creation-text-box.png

  • 在新分支中创建一个 PR,使用 <originalRepo/master> 作为基础
  • 在创建 PR 之前进行基础切换

https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2016/02/1454845571Screenshot-2016-02-07-12.41.28-1024x411.png

https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2016/02/1454964017Screenshot-2016-02-07-12.41.42.png

那是一个人为强制刷新“upstream/master”的步骤。您可以使用“合并拉取请求”按钮(然后是“确认合并”)创建并合并它:合并将是微不足道的,没有合并提交。最终结果是:您自己的“master”分支(在您的fork中)已更新为“upstream/master”(原始存储库的“master”分支)!然后,您可以恢复我上面描述的步骤,并将当前PR的基础更改为您自己(现在已刷新)的“master”分支,看看是否可以重新设置基础!

如果我理解正确的话,这种方式fork永远不会被更新,因此随着时间的推移,fork将变得越来越过时,到最后进行rebase合并就会变得不可行。 - brentonstrine
这非常聪明,顺便说一下,感谢您思考如何做到这一点。 - brentonstrine
@brentonstrine 不是的,分支已经更新了:更准确地说,首先更新了分支的主分支(代表上游/主分支的原始状态),然后再将您的PR分支变基。 - VonC
它不起作用。仍然有三种可能性:两种会创建合并提交,而“Rebase and merge”则表示存在冲突,即使我没有在派生主分支中更改任何内容。 - int_ua
1
@int_ua 好的,如果你在那里找到解决方案,请告诉我,我不监控Web应用程序,只监控Stack Overflow(那里有40000多个GitHub问题,而Web应用程序只有371个)。 - VonC
显示剩余2条评论

12

自GitHub Desktop 1.0.7版本 开始,这是可行的,需要考虑以下几点:

如果当前分支没有领先于上游(分叉的原始存储库)的提交,则可以在不创建新合并提交的情况下拉取新提交。
在GitHub桌面应用程序中:
1. 从“文件>克隆存储库”克隆您的存储库 2. 执行“获取原点”,这将自动获取上游 3. 单击“当前分支”处,进入“分支” 4. 单击底部的“选择要合并到<分支>的分支” 5. 搜索“upstream/”,然后单击“将upstream/合并到” 6. 推送到origin,就完成了!
否则,如果当前分支领先于分叉,则必须创建一个合并提交或进行rebase和强制推送。对于更可取的rebase,请执行以下操作:
1. 在GitHub桌面应用程序中,从菜单中转到“分支”,然后转到“重新设置当前分支” 2. 搜索“upstream/”,然后单击“开始rebase” 3. 解决由rebase引起的任何冲突 4. 强制推送到origin。由于明显的原因,您会收到警告。
为了避免在当前分支同时领先和落后于上游分支时强行推送你的工作,要么创建一个新的合并提交,要么:
  • 基于所有更改创建一个新的分支

  • 如果需要,将原始分支重置为其分离原始存储库之前的状态

  • 执行第一种情况下的步骤,并将更改合并到你的分支中。

是的,在此时似乎无法通过GitHub网站从原始存储库拉取而不创建拉取请求和合并提交。


第一个场景的演示GIF: https://imgur.com/a/8wci2yf

与此相关的一些GitHub问题:


你有尝试过这种方法吗?有任何问题或观察到的情况吗?按照说明可能看起来是一个漫长的过程,但实际上只需要大约30秒就能完成。 - Siavas
你点击了Fetch吗,@brentonstrine?有一个链接的GIF向你展示如何从那里操作。你是否拥有最新版本的GitHub桌面版? - Siavas
是的,那就是问题所在,我刚意识到并删除了我的评论。 - brentonstrine
没问题@brentonstrine。如果有什么我可以做的来澄清这些步骤,请告诉我。 - Siavas
重定基特性自1.0.7版本起就已经可用了吗?我知道在2.0版本发布后不久(这个问题被提出的几天后)进行了一次改进以帮助重定基 - 在2.0版本之前,我并不知道有重定基的能力。 - brentonstrine
根据于2017年11月2日提交的此GitHub拉取请求,似乎他们添加了从上游获取数据的功能,该功能允许通过“与upstream/<branch>合并”功能进行变基。我认为变基功能本身确实是最近才添加的。 - Siavas

5

更新 注意:以下非命令行方式可能会有所帮助: 有没有办法让GitHub桌面版对主分支进行变基?

关键是要执行变基操作,因此上述答案应该有所帮助。


命令行方式(更简单,使用git,因此默认情况下应该更全面)

有一些实践方法可以避免这种情况的发生。

  • 不要在您的派生分支上工作。
$ git clone <your fork>
$ git checkout -b feature_branch

你可以在自己的feature_branch上工作,然后发起一个拉取请求(Pull Request)。

  • 一旦你的更改合并到上游主分支(upstream master),你就可以从上游拉取到你的本地仓库(origin)。由于上游主分支已经整齐地包含了你的提交,所以这时不会出现合并提交(merge commit)。
$ git checkout master
$ git pull upstream master
$ git push origin master
  • 如果维护者已经与您 fork 的主分支有所不同,也就是说,它不再是线性的,则需要拉取一份最新的副本。由于您的更改已经在上游,这应该不会成为问题。

  • 如果您在处理 PR 时,上游的主分支已经向前移动,则可以在您的 feature_branch 上进行变基。

$ git checkout master
$ git pull upstream master
$ git push origin master
$ git checkout feature_branch
$ git rebase master

请参考此文档获取详细参考资料:Fork 和 pull request 工作流程

2
CLI指的是命令行界面。因此,您回答中以“$”开头的所有行都属于CLI。我试图让我的问题非常清楚,我不是在寻找CLI解决方案。您能否给我一些建议,如何使我的问题更清晰,表明我不是在寻找CLI解决方案? - brentonstrine
有一种使用Github桌面版进行变基的方法,这可能会有所帮助。我通常不使用UI,因为它会使事情变得有点复杂。我使用UI的唯一原因是在提交时部分选择行,并将现有提交拆分成较小的提交,因为在CLI中有点困难。 - prateeknischal
1
@brentonstrine 很清楚。这个特定的答案之所以出现,很可能是因为悬赏。如果有至少2个赞,最高得票的答案在期限结束后如果没有选择任何答案,则获得一半的悬赏声望,因此如果这个答案是最高得票的...(参考:https://meta.stackexchange.com/questions/16065/how-does-the-bounty-system-work)。在这种情况下最好的做法是,如果这个答案没有解决您的问题,请投反对票并继续前进。 - rayryeng
1
在pikaynu的情况下,他们在我创建悬赏之前发布了他们的答案。 - brentonstrine
为了辩护自己,是的,我没有看到赏金,也没有为赏金发布帖子。感谢@brentonstrine. :) - prateeknischal
我很感激这个答案,因为我在网上搜索CLI解决方案时@brentonstrine没有提供。谢谢pika-dude!(如果我不再评论,也意味着这个方法可行) - cregox

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