[英]Git Workflow for Multiple Feature Branches
Let's say I'm working on a feature that involves changes to multiple components of a system.假设我正在开发一个涉及对系统多个组件进行更改的功能。 As an example, let's say I need to update a daemon, server, and client.
例如,假设我需要更新守护程序、服务器和客户端。 My current workflow would leave me with branches/commits like this:
我当前的工作流程会给我留下这样的分支/提交:
m1---m2---m3 <- master
\
d1---d2 <- daemon
\
s1---s2 <- server
\
c1---c2 <- client
With these branches, I could create 3 pull requests on GitHub, merging client -> server
, server -> daemon
, and daemon -> master
.有了这些分支,我可以在 GitHub 上创建 3 个拉取请求,合并
client -> server
、 server -> daemon
和daemon -> master
。 This all works fine, until I need to add a commit on a branch other than client
.这一切都很好,直到我需要在
client
以外的分支上添加提交。 For example, let's say I make a commit on daemon
:例如,假设我在
daemon
上提交:
m1---m2---m3 <- master
\
d1---d2---d3 <- daemon
\
s1---s2 <- server
\
c1---c2 <- client
Now I'm left in "rebase hell", where I need to rebase server
onto daemon
, client
onto server
, etc. Is there a way to move s1
to d3
and take downstream branches like client
with it in one command?现在我留在“变基地狱”中,我需要将
server
变基到daemon
,将client
变基到server
等。有没有办法将s1
移动到d3
并在一个命令中使用它的下游分支,如client
? Thus leaving a final state like this and my pull requests in tact:因此留下一个像这样的最终 state 和我的拉取请求:
m1---m2---m3 <- master
\
d1---d2---d3 <- daemon
\
s1---s2 <- server
\
c1---c2 <- client
In theory you should only need to merge daemon
and client
with master
if you're branching in this manner but, it's not really an ideal way to split work unless each upstream change is dependent on the previous component and even then you might want to save integration for the overall feature release/merge rather than doing it at each child component.从理论上讲,如果您以这种方式分支,您应该只需要将
daemon
和client
与master
合并,但是,除非每个上游更改都依赖于前一个组件,否则这并不是拆分工作的理想方式,即使那样您可能想要保存集成整体功能发布/合并,而不是在每个子组件上进行。
In Example 2 all commits but d3
are already in client
so you could simplify your workflow(s) to either 1, 2, or 3 steps:在示例 2 中,除
d3
之外的所有提交都已在client
中,因此您可以将工作流程简化为 1、2 或 3 个步骤:
client -> master
brings in everything.client -> master
带来一切。client -> master
brings in everything but d3
.client -> master
会引入除d3
之外的所有内容。 Cherry pick (or rebase commit only) d3
to client or master. d3
到客户端或主控。daemon -> client -> master
would bring in d3
and server
.daemon -> client -> master
将引入d3
和server
。daemon
, server
) before downstream PR ( client -> master
).client -> master
) 之前合并上游分支 ( daemon
, server
)。 A safer way to do this might be to simply branch master once to create an integration branch and then branch and merge (when resolving) each component so you can test their interoperability without updating your production branch.一个更安全的方法可能是简单地将 master 分支一次以创建一个集成分支,然后分支并合并(在解析时)每个组件,这样您就可以在不更新生产分支的情况下测试它们的互操作性。 This would be where you're doing reviews and then merging that to master once release is ready.
这将是您进行审核的地方,然后在发布准备好后将其合并以掌握。
This, of course, means 1 more merge rather fewer but wouldn't involve branching feature chaining and would make it easier to catch bugs before release.当然,这意味着 1 次合并而不是更少,但不会涉及分支功能链,并且会更容易在发布之前捕获错误。 Sometimes you don't want the fewest merges or the cleanest history, you want guardrails.
有时您不想要最少的合并或最干净的历史记录,您需要护栏。
It may feel like it's "rebase hell", but the reality is you only need a single rebase command, and then you simply need to repoint the middle branch(es) to their new respective commits.感觉就像是“变基地狱”,但实际上您只需要一个变基命令,然后您只需将中间分支重新指向它们各自的新提交。 So that's 1 rebase command followed by
n-2
branch resets, where n
is the number of PR's (branches) you will have.所以这是 1 个 rebase 命令,然后是
n-2
分支重置,其中n
是您将拥有的 PR(分支)的数量。 In your example with 3 branches it's kind of a two-liner:在您的带有 3 个分支的示例中,它是一种两条线:
git rebase d2 client --onto d3
# Now for each middle branch, reset to the corresponding new commit ID:
# Look at the log of client to see the new s2 ID
git branch -f server <new-commit-id-of-s2>
If you had many branches chained in this way or you needed to do this often, surely you could automate the reset portion if desired (eg commit messages and author name/dates will be the same, etc).如果您有许多以这种方式链接的分支,或者您需要经常这样做,那么您当然可以根据需要自动执行重置部分(例如,提交消息和作者姓名/日期将相同等)。 However, considering that branching in this way is (generally) a theoretical anti-pattern, I hope it wouldn't happen often enough to warrant spending too much time automating something that can be done manually quickly enough.
但是,考虑到以这种方式进行分支(通常)是一种理论上的反模式,我希望它不会经常发生,以至于需要花费太多时间来自动化可以足够快地手动完成的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.