多个开发人员处理同一任务的正确 git 工作流程方案

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14865283/
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-10 15:30:34  来源:igfitidea点击:

Proper git workflow scheme with multiple developers working on same task

gitworkflowbitbucketbranching-and-merging

提问by Viktor Livakivskyi

I'm a team leader in our web development company, and I'd like to implement Git workflow in our team. Reading documentation and articles I've found the following structure good for us:

我是我们 Web 开发公司的团队负责人,我想在我们的团队中实施 Git 工作流程。阅读文档和文章,我发现以下结构对我们有好处:

We have a repository in a Bitbucket. Masterbranch is considered to contain stable code only. Every dev must create his own branch and implement features/bugfixes in his ownbranch. Once he decides, that his code is ready, he creates a nice branch history (using rebase, amend, cherry-pick etc.) and pushes it to Bitbucket, where creates a pull request to master branch. QA verifies functionality and approves (or disapproves) it, then I'm verifying code and if it is ok, I merge his work into master (by fast-forward or rebasing for better commits history).

我们在 Bitbucket 中有一个存储库。Master分支被认为只包含稳定的代码。每个开发必须建立自己的分公司,并实现他的特点/ bug修正自己的分公司。一旦他决定,他的代码已经准备好了,他就会创建一个不错的分支历史记录(使用 rebase、amend、cherry-pick 等)并将其推送到 Bitbucket,在那里创建一个对 master 分支的拉取请求。QA 验证功能并批准(或不批准)它,然后我正在验证代码,如果没问题,我将他的工作合并到 master 中(通过快进或 rebase 以获得更好的提交历史)。

But this scheme is good only in a case, when single developer works on a branch. In our case we almost always have two developers for one branch, since one developer is working on server-side(PHP), and another - client-side(HTML/CSS/JS). How these two should collaborate in a way, that commit history in master stays clean?

但这种方案仅适用于单个开发人员在分支上工作的情况。在我们的例子中,一个分支几乎总是有两个开发人员,因为一个开发人员在服务器端(PHP) 工作,而另一个在客户端(HTML/CSS/JS)。这两者应该如何协作,使 master 中的提交历史保持干净?

Server dev creates basic structure of HTML files and client dev needs to get this structure. Logically would be for server dev to create a branch, and for client dev to create his own branch, based on server dev branch. But this means, that server dev needs to publishhis branch in Bitbucket, which will make it impossible for him to rebase or change commits, that are already published.

服务器开发人员创建 HTML 文件的基本结构,客户端开发人员需要获取此结构。从逻辑上讲,服务器开发人员创建一个分支,客户端开发人员基于服务器开发分支创建自己的分支。但这意味着,该服务器开发人员需要在 Bitbucket 中发布他的分支,这将使他无法重新设置或更改已经发布的提交

Another option is to wait, until server dev finishes his work, publishes branch with nice commits history and forgets about it, and only after that client dev starts to work in this branch, but this will cause time delays, which is even worse.

另一种选择是等待,直到 server dev 完成他的工作,发布具有良好提交历史的分支并忘记它,并且只有在该 client dev 开始在该分支中工作之后,但这会导致时间延迟,这更糟糕。

How do you handle such a collaboration in your workflows?

您如何在工作流程中处理这种协作?

回答by bronzehedwick

I can't really speak to the merits of the methods described in your post, but I can describe how we solved collaborative coding in the workflow we use at work.

我不能真正谈论您帖子中描述的方法的优点,但我可以描述我们如何在工作中使用的工作流程中解决协作编码。

The workflow we use is one of many branches. Our structure is thus:

我们使用的工作流是众多分支之一。我们的结构是这样的:

Master is golden; only the merge master touches it (more on this in a bit).

师父是金;只有合并大师会触及它(稍后会详细介绍)。

There is a dev branch, taken initially from master, that all devs work off. Instead of having a branch per developer, we make feature, or ticket, branches from dev.

有一个开发分支,最初取自 master,所有开发人员都可以使用。我们不是为每个开发人员设置一个分支,而是从开发人员创建功能或票证分支。

For every discreet feature (bug, enhancement, etc.), a new local branch is made from dev. Developers don't have to work on the same branch, since each feature branch is scoped to only what that single developer is working on. This is where git's cheap branching comes in handy.

对于每个谨慎的功能(错误、增强等),一个新的本地分支由 dev 生成。开发人员不必在同一个分支上工作,因为每个功能分支的范围仅限于单个开发人员正在处理的内容。这就是 git 的廉价分支派上用场的地方。

Once the feature is ready, it's merged locally back into dev and pushed up to the cloud (Bitbucket, Github, etc.). Everyone keeps in sync by pulling on dev often.

一旦该功能准备就绪,它就会在本地合并回 dev 并推送到云端(Bitbucket、Github 等)。每个人都通过经常拉动开发来保持同步。

We are on a weekly release schedule, so every week, after QA has approved the dev branch, a release branch is made with the date in the name. That is the branch used in production, replacing last week's release branch.

我们按周发布时间表,所以每周,在 QA 批准 dev 分支后,都会创建一个名称中带有日期的发布分支。那是生产中使用的分支,替换上周的发布分支。

Once the release branch is verified by QA in production, the release branch is merged back into master (and dev, just to be safe). This is the only time we touch master, ensuring that it is as clean as possible.

一旦发布分支在生产中通过 QA 验证,发布分支就会合并回 master(和 dev,只是为了安全)。这是我们唯一一次接触 master,确保它尽可能干净。

This works well for us with a team of 12. Hopefully it's been helpful. Good luck!

这对我们 12 人的团队很有效。希望它有所帮助。祝你好运!

回答by Hugh

We have a principal repository and each developer has a fork of that.

我们有一个主要存储库,每个开发人员都有一个分支。

A branch is created principal/some_project, the same branch name is then created on each developers' fork, fork/some_project.

创建一个分支principal/some_project,然后在每个开发者的fork上创建相同的分支名称,fork/some_project。

(We use smartgit and we also have a policy that remotes are named 'principal' and 'fork' rather than 'origin' and 'upstream' which just confuse new users).

(我们使用 smartgit 并且我们还有一项政策,即遥控器被命名为“principal”和“fork”,而不是“origin”和“upstream”,这只会让新用户感到困惑)。

Each developer also has a local branch named some_project.

每个开发人员还有一个名为 some_project 的本地分支。

The developers local branch some_project tracks the remote branch principal/some_project.

开发人员本地分支 some_project 跟踪远程分支 principal/some_project。

Developers do their local work on branch some_project and push-to to their fork/some_project, from time to time they create pull requests, this is how each developer's work gets merged into principal/some_project.

开发人员在分支 some_project 上进行本地工作并推送到他们的 fork/some_project,他们不时创建拉取请求,这就是每个开发人员的工作合并到 principal/some_project 的方式。

This way developers are free to pull/rebase locally and push to their forks - this is pretty much the standard fork workflow. This way they get other developers' commits and may from time to time have to resolve the odd conflict.

通过这种方式,开发人员可以自由地在本地拉/变基并推送到他们的分叉 - 这几乎是标准的分叉工作流程。通过这种方式,他们可以获得其他开发人员的提交,并且可能需要不时解决奇怪的冲突。

This is fine and all that's needed now is a way to merge in ongoing updates that appear in principal/master (for example urgent fixes or other projects that are delivered before some_project is finished).

这很好,现在所需要的只是一种合并出现在主体/主文件中的正在进行的更新的方法(例如,在 some_project 完成之前交付的紧急修复或其他项目)。

To acomplish this we designate a 'branch lead' their role is to locally merge updates from master into some_project using merge (not pull, rebase) in SmartGit. This too may sometimes generate conflicts and these must be resolved. Once this is done that developer (the branch lead) force pushes to their fork/some_project branch then creates a pull request to merge into principal/some_project.

为了实现这一点,我们指定了一个“分支负责人”,他们的作用是使用 SmartGit 中的合并(而不是拉取,变基)将 master 的更新本地合并到 some_project 中。这有时也会产生冲突,必须解决这些冲突。完成此操作后,开发人员(分支负责人)强制推送到他们的 fork/some_project 分支,然后创建合并到 principal/some_project 的拉取请求。

Once that pull request is merged, all of the new commits that were on principal/master are now present on the principal/some_project branch (and nothing was rebased).

合并拉取请求后,所有在 principal/master 上的新提交现在都出现在 principal/some_project 分支上(并且没有任何内容被重新定位)。

Therefore the next time each developer is on some_project and pulls (recall, their tracked branch is principal/some_project) they'll get all of the updates which will include the stuff merged from principal/master.

因此,下次每个开发人员在 some_project 上并拉取(回想一下,他们跟踪的分支是 principal/some_project)时,他们将获得所有更新,其中包括从 principal/master 合并的内容。

This may sound long winded but it's actually fairly simple and robust (every developer could also just merge locally from principal/master but it's neater if one person does that, the rest of the team live in a simple world much like the single developer workflow).

这可能听起来很啰嗦,但实际上相当简单和健壮(每个开发人员也可以从主体/主服务器本地合并,但如果一个人这样做会更整洁,团队的其他成员生活在一个简单的世界中,就像单个开发人员的工作流程一样) .

回答by Diego V

I think still nobody actually answered the original question of how to collaborate in topic branches maintaining a clean history.

我认为仍然没有人真正回答了如何在主题分支中进行协作以保持干净的历史的原始问题。

The proper answer is sorry, you can't have all that together. You only can groom your private local history, after you publish something for others you should work on top of that.

正确的答案是抱歉,您不能将所有这些放在一起。您只能修饰您的私人本地历史记录,在为他人发布某些内容后,您应该在此基础上继续工作。

The best you could do in your particular case where server dev doesn't care about client dev changes is to locally fork client branches from dev/feature ones and rebase that part on top of server work just before finishing the feature —or relax your constraints and switch to a different workflow, as you did ;)

在服务器开发不关心客户端开发更改的特定情况下,您可以做的最好的事情是在本地从开发/功能分支中分叉客户端分支,并在完成功能之前将该部分重新定位在服务器工作之上 - 或者放松您的约束并像您一样切换到不同的工作流程;)

回答by Steven Penny

which will make it impossible for him to rebase or change commits, that are already published.

这将使他无法重新设置或更改已经发布的提交。

This depends on your audience. "Server dev" can push the "basic structure" to Bitbucket so that "client dev" will have access to it. Yes this does potentiallymean that others will have access to these "temporary" commits.

这取决于你的听众。“服务器开发人员”可以将“基本结构”推送到 Bitbucket,以便“客户端开发人员”可以访问它。是的,这可能意味着其他人将可以访问这些“临时”提交。

However this would only be an issue if another user branched from one of these commits beforethey were rebased. On a smaller project/smaller userbase these temporary commits might never be noticed even before the rebase occured, hence negating the risk.

然而,如果另一个用户重新定位之前从这些提交之一分支,这只会是一个问题。在较小的项目/较小的用户群中,即使在 rebase 发生之前,这些临时提交也可能永远不会被注意到,因此消除了风险。

The decision is yours if the risk of someone branching from these temporary commits is too great. If so then you would need to perhaps create a second private Bitbucket repo for these private changes. Another option would be to do merge commitsinstead of rebasing, but this is also not ideal.

如果有人从这些临时提交中分支的风险太大,则由您决定。如果是这样,那么您可能需要为这些私有更改创建第二个私有 Bitbucket 存储库。另一种选择是进行合并提交而不是变基,但这也不理想。

回答by saket

回答by Mohan Sharma

Let me tell you what we do here while multiple developers working on the same project (even sometimes working on the same controllers/models/views).

让我告诉你,当多个开发人员在同一个项目上工作(甚至有时在同一个控制器/模型/视图上工作)时,我们在这里做什么。

First of all our team-lead created git-project with two branches

首先我们的团队负责人创建了带有两个分支的 git-project

  1. Master (it is protected one, no one can push here except team-lead)
  2. Development (all developers can push here)
  1. 大师(是保护的,除了领队外谁都不能推这里)
  2. 开发(所有开发者都可以在这里推送)

They told us to work on our local environment and create commits whenever we completed one of assigned task(s).

他们告诉我们在我们的本地环境中工作,并在我们完成分配的任务之一时创建提交。

Now in the evening-time (or say closing time - leaving), we do this :

现在在晚上(或者说关闭时间 - 离开),我们这样做:

  1. Git Pull
  1. Git 拉取

Every developer that are working on the same project Pull current development branch to their local (do same in morning - when starting for day).

每个在同一个项目上工作的开发人员将当前的开发分支拉到他们的本地(早上做同样的事情 - 一天开始时)。

Then team-lead told developer to commit all codes and push one by one followed by one pull.

然后团队负责人告诉开发人员提交所有代码并一一推一拉。

For ex.

例如。

  • dev1 creates commit and pushes to server
  • dev2 pulls again and creates commit and push
  • dev3 pulls again and creates commit and push
  • and so on..
  • dev1 创建提交并推送到服务器
  • dev2 再次拉取并创建提交和推送
  • dev3 再次拉取并创建提交和推送
  • 等等..

Now the problem is conflicts :

现在的问题是冲突:

  • Sometime while pulling code from development branch git notifies that we merged all conflicts automatically --- that means git automatically applied new changes made by another developer
  • But sometime the SAME git tells that automatic merge failed and shows some filenames
  • then team-lead role comes into picture -- what he does is : "He reviews all listed files (during automatic merge failed process) and merges conflicts manually and creates commit and push to server.
  • 有时在从开发分支中提取代码时,git 通知我们自动合并了所有冲突 --- 这意味着 git 自动应用了另一个开发人员所做的新更改
  • 但有时 SAME git 告诉自动合并失败并显示一些文件名
  • 然后团队领导角色出现 - 他所做的是:“他所有列出的文件(在自动合并失败过程中)并手动合并冲突并创建提交并推送到服务器。

Now how to merge manually : GIT simply updates conflict files with all contents like this :

现在如何手动合并:GIT 只是更新冲突文件的所有内容,如下所示:

<<< HEAD
New lines from server that you don't have is here shown
=====
Your current changes....
>>> [commit id]

Team-lead updates that file after analyzing to this :

团队负责人在分析后更新该文件:

 New lines from server that you don't have is here shown
 Your current changes

and creates commit and push.

并创建提交和推送。

Again in morning we do pull (just to make sure that we didn't miss anything from previous day), This is how we work here.

早上我们再次拉动(只是为了确保我们没有错过前一天的任何东西),这就是我们在这里工作的方式。

回答by Josef.B

For the exact question, multiple developers on the same task, the short answer is the task is done in an integration branch for that task. That 'task' branch is treated just like "master" or "dev" branches in the usual Git workflows (as most answers here provided). This integration branch is processed in the "Git Feature Branch Workflow" elaborated elsewhere.

对于确切的问题,多个开发人员执行同一任务,简短的回答是该任务在该任务的集成分支中完成。该“任务”分支在通常的 Git 工作流程中被视为“主”或“开发”分支(如此处提供的大多数答案)。这个集成分支是在别处详述的“Git Feature Branch Workflow”中处理的。

This task branch is where the devs working on that task share code using the normal Git commands.

这个任务分支是处理该任务的开发人员使用普通 Git 命令共享代码的地方。

Example

例子

To develop the new splash screen, the Lead developer (or someone) does

为了开发新的启动画面,首席开发人员(或某人)

git co master
git co -b feature-splash
git push origin feature-splash

Each developer working on this feature does:

从事此功能的每个开发人员都会:

git co master
git pull
git co feature-splash
git co -b my-feature-splash  // they can name their branch whatever

Now each dev will develop on their branch and create pull requests toward merges on the feature-splash on the central Git repo server like GitHub. Just like it is done for the sacrosanct 'master' branch.

现在,每个开发人员都将在他们的分支上进行开发,并在中央 Git 存储库服务器(如 GitHub)上的功能飞溅上创建合并请求。就像为神圣不可侵犯的“主”分支所做的那样。

When the feature is done, the feature-splash is merged into master. Of course, this feature-splash must be kept up to date with new code on master. Could the feature-splash use rebasing on master?

功能完成后,功能飞溅将合并到主文件中。当然,这个特性飞溅必须与 master 上的新代码保持同步。功能飞溅可以使用基于主的变基吗?

This is not my original idea. I read about this in various places. Note that in many workflow articles this task specific branch is not really a concept. For example, in one article we have "Feature branches typically exist in developer repos only, not in origin." Perhaps a task that requires more than one developer is always broken down into subtasks? I guess if you know the future and know what is required.

这不是我最初的想法。我在很多地方都读到过这件事。请注意,在许多工作流文章中,此特定于任务的分支实际上并不是一个概念。例如,在一篇文章中,我们有“特性分支通常只存在于开发者存储库中,而不存在于源中”。也许一项需要多个开发人员的任务总是被分解为子任务?我想如果你知道未来并知道需要什么。

回答by Nirav Bhatt

The rules to remember are:

要记住的规则是:

  • Have 1 masterand 1 developbranch
  • Have feature branches spawn off of developbranch
  • Every time you have version ready for QAto test, merge into develop
  • Have release branches spawn off of developbranch
  • Make bugfixes into release branches
  • When you have version ready for QAto test, merge into develop
  • When you have version ready for PRODUCTION, merge into master, and create a tag for it
  • 有1个master和1个develop分支
  • 有功能分支产卵关闭的develop分支
  • 每次你有版本准备好进行QA测试时,合并到develop
  • 已发布分支产卵关闭的develop分支
  • 将错误修正放入发布分支
  • 当您准备好进行QA测试的版本时,合并到develop
  • 当您为PRODUCTION准备好版本时,合并到master并为其创建一个标记

Following diagram is the bull's eye strategy followed in teams across the world (Credit: taken from here):

下图是世界各地团队遵循的靶心策略(来源:取自此处):

enter image description here

在此处输入图片说明