Proper git workflow scheme with multiple developers working on same task

GitWorkflowBitbucketBranching and-Merging

Git Problem Overview


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:

We have a repository in a Bitbucket. Master branch is considered to contain stable code only. Every dev must create his own branch and implement features/bugfixes in his own branch. 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).

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?

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 publish his branch in Bitbucket, which will make it impossible for him to rebase or change commits, that are already published.

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.

How do you handle such a collaboration in your workflows?

Git Solutions


Solution 1 - Git

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.

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.

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.

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.

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.

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

Solution 2 - Git

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 ;)

Solution 3 - Git

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.

(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).

Each developer also has a local branch named some_project.

The developers local branch some_project tracks the remote branch 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.

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).

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.

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).

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.

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).

Solution 4 - Git

The rules to remember are:

  • Have 1 master and 1 develop branch
  • Have feature branches spawn off of develop branch
  • Every time you have version ready for QA to test, merge into develop
  • Have release branches spawn off of develop branch
  • Make bugfixes into release branches
  • When you have version ready for QA to test, merge into develop
  • When you have version ready for PRODUCTION, merge into master, and create a tag for it

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

enter image description here

Solution 5 - Git

> 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 potentially mean that others will have access to these "temporary" commits.

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

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 commits instead of rebasing, but this is also not ideal.

Solution 6 - Git

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

  1. Master (it is protected one, no one can push here except team-lead)
  2. Development (all developers can push here)

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

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..

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.

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

<<< 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.

Solution 7 - Git

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.

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

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.

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?

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.

Solution 8 - Git

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionViktor LivakivskyiView Question on Stackoverflow
Solution 1 - GitbronzehedwickView Answer on Stackoverflow
Solution 2 - GitDiego VView Answer on Stackoverflow
Solution 3 - GitHughView Answer on Stackoverflow
Solution 4 - GitNirav BhattView Answer on Stackoverflow
Solution 5 - GitZomboView Answer on Stackoverflow
Solution 6 - GitMohan SharmaView Answer on Stackoverflow
Solution 7 - GitJosef.BView Answer on Stackoverflow
Solution 8 - GitsaketView Answer on Stackoverflow