Git:如何维护永久并行分支

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2170179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 04:03:32  来源:igfitidea点击:

Git: how to maintain permanent parallel branches

gitmergebranchrebase

提问by Stepan

We have project (PHP application), but instalation for each client vary, sometimes very little, sometimes more. Still, big part of source code is common. We manage specific installations as parallel branches to master branch and we need to transfer changes from master to other branches. Same situation was solved in Git: how maintain (mostly) parallel branches with only a few difference?The most voted solution was to transfer changes between braches this way:

我们有项目(PHP 应用程序),但每个客户端的安装各不相同,有时很少,有时更多。尽管如此,源代码的很大一部分是常见的。我们将特定安装作为并行分支管理到 master 分支,我们需要将更改从 master 转移到其他分支。在Git中解决了相同的情况:如何维护(大部分)并行分支,只有一些区别?投票最多的解决方案是以这种方式在分支之间传输更改:

git pull
git checkout local
git rebase master

As mentioned in the solution it creates non-fast-forward pushes after rebasing which I find very unpleasant complication. My QUESTION is - why not to do instead:

正如解决方案中提到的,它在重新定位后创建了非快进推送,我发现这是非常令人不快的并发症。我的问题是 - 为什么不这样做:

git pull
git checkout local
git merge master

采纳答案by John Stoneham

It really depends on what you want to do with the branch. Yes, if you rebase local, it'll create non-fast-forward pushes after rebasing. On the other hand, you'll be maintaining a set of distinct changes going forward and what's on your branch will be a set of changes AS IF THEY HAD BEEN MADE TO THE NEWEST HEAD OF MASTER.

这真的取决于你想用分支做什么。是的,如果您在本地重新定位,它会在重新定位后创建非快进推送。另一方面,您将在未来维护一组不同的更改,并且您的分支上的内容将是一组更改,就好像它们是对最新的 MASTER 负责人所做的一样。

Merging the master to local, instead, will keep local marching forward in time with master, and will record the history as it happened. If you need to be able to reconstruct the state of local in the past, then you'll want to do this. The history will never change. But, you'll have a more complicated history to deal with.

相反,将 master 合并到 local 将保持本地与 master 同步前进,并将记录发生的历史。如果您需要能够重建本地过去的状态,那么您会想要这样做。历史永远不会改变。但是,您将需要处理更复杂的历史记录。

回答by Old McStopher

The idea is you use one common branch, and two (or as many as you need) customer specific branches. All common changes go into the master, and each customer branch gets changes that pertain only to that customer. Periodically (when master is considered to be at a stable point), you'll merge changes from master into the customer branch (git checkout custA; git merge master). This brings in newer "common" code into the customer branch. You will never merge the other way -- that would pollute master with customer-specific code.

When you make a delivery to customer A, you checkout the "custA" branch and send that. And of course similarly for other customers.

Now let's say you acquire a new customer, "C", and a bit later find a feature that customers A and C want, but B doesn't. You create (aka "fork") a branch off of master (git checkout -b AC_feature master), code/test it, making commits as you go, and then merge it into A and C (git checkout A; git merge AC_feature and similarly for customer C). You do not code it in A and then rely on merging A into C, because that would get all of A into C.

If, sometime later, you find a minor bug in that feature, you make the change in the same branch (git checkout AC_feature; edit/test/commit), and then you merge it into custA and custC as above.

这个想法是您使用一个公共分支和两个(或您需要的多个)特定于客户的分支。所有常见的更改都进入主服务器,每个客户分支都会获得仅与该客户相关的更改。定期(当认为 master 处于稳定点时),您将从 master 合并更改到客户分支 ( git checkout custA; git merge master)。这将更新的“通用”代码引入客户分支。您永远不会以其他方式合并——这会用客户特定的代码污染 master。

当您向客户 A 交货时,您结帐“custA”分支并将其发送。当然,对于其他客户也是如此。

现在假设您获得了一个新客户“C”,稍后找到客户 A 和 C 想要但 B 不需要的功能。您从 master ( git checkout -b AC_feature master)创建(又名“fork”)一个分支,对其进行编码/测试,随时提交,然后将其合并到 A 和 C ( git checkout A; git merge AC_feature and similarly for customer C) 中。您不会在 A 中对其进行编码,然后依靠将 A 合并到 C 中,因为这会将所有 A 合并到 C 中。

如果稍后您在该功能中发现了一个小错误,则在同一分支 ( git checkout AC_feature; edit/test/commit) 中进行更改,然后将其合并到 custA 和 custC 中,如上所述。

Source:These refreshingly clear and helpful articles from the developer of Gitolite - Sitaram Chamarty, written in part with direct input from Junio Hamano (Linus Torvalds' partner in maintaining Git).

来源:这些来自 Gitolite 开发人员的清晰而有用的文章 - Sitaram Chamarty,部分内容来自 Junio Hamano(Linus Torvalds 的 Git 维护合作伙伴)的直接输入。

Maintaining Parallel Customer Branches:

维护并行客户分支:

http://gitolite.com/archived/special-branches.html

http://gitolite.com/archived/special-branches.html

Followup Article on "Fixing Up" Common and Customer Branches:

关于“修复”公共和客户分支的后续文章:

http://gitolite.com/archived/special-branch-fixups.html

http://gitolite.com/archived/special-branch-fixups.html

回答by Greg Bacon

Greg's answerto your other question seems to view different branches as remaining local to particular installations, not pushed to other repos (emphasis added):

Greg对您的另一个问题的回答似乎将不同的分支视为保留在特定安装的本地,而不是推送到其他存储库(强调):

If it's local to a system, commit it to that system's "local" branch, else commit it to "master" and push it up to a common repository.

如果它是系统本地的,则将其提交到该系统的“本地”分支,否则将其提交给“主”并将其推送到公共存储库。

You almost always want fast-forward pushes to branches in a shared repository. The git rebasedocumentationexplains how to recover from an upstream rebase (i.e., git rebasethen git push -f), and it's no fun for anyone involved.

您几乎总是希望快进推送到共享存储库中的分支。该git rebase文档解释了如何从上游 rebase(git rebasethen git push -f)中恢复,并且对于任何相关人员来说都没有乐趣。

For another approach, see Never merging back:

对于另一种方法,请参阅永不合并

There are valid cases where you once fork with the intention to never merge back, but in general you should try very hard to keep changes on such a fork to the minimum.

在某些情况下,您曾经分叉并打算永远不会合并回来,但通常您应该非常努力地将此类分叉上的更改保持在最低限度。

The author goes on to discuss branching policy for various customer releases within the same repository.

作者继续讨论同一存储库中各种客户版本的分支策略。