Apologies up front for a long article but I need to know what the community does as far as development cycles and how you deal with everyday release problems.
I have been working with Git for 5+ years and my first encounter was forced on me as I was the only one capable of pulling off a full implementation for our group of developers.
We did not have Atlassian's products and the company wouldn't buy them for some reason. However, they did spring for Git Enterprise as our company didn't use cloud based products at the time. So, using command line git, I taught myself everything I could in as little time as I could, so the developers would have a bit of sanity in their everyday workload.
My adopted workflow:
I had heard of other workflows that other companies used and most of them did not make any sense.
In my last job where I learned release methodologies and built a custom deployment system using cron based bash scripts, I devised a way for our developers to continuously push changes to our environments with specific control of promotions in the hands of the developers. Since they were responsible for seeing their changes through to production, it only made sense that after a successful test of the feature branch by the QA team, they would see to it that their changes were merged into production.
This was a PHP development team and therefore did not need any included libraries and other necessities like a Java/C/C++ developer would need.
On the central repository, I first created the repository and updated the master branch with what was currently in production. Then, I created 2 "release" branches off of master called "Development" and "QA." The idea was that the release branches mirrored exactly what was on the target server environments.
The first thing a developer would do is create a feature branch off of master. The reason for this is the feature branch would eventually be promoted to master and no other changes from the other environments needed to be put in master. Only the changes in that feature branch.
Once the developer was finished with the feature, they would add/commit/push their feature branch to the repository. They would then create a Pull Request and merge into the Development release branch. This would be picked up by the script on the deployment server, which was a separate server only for the purpose of deploying, and be rsynced to the Development server for whatever testing the developer wanted to do. Once they were ready, they would then create another Pull Request and merge the feature branch into the QA release branch. Once the changes were tested, the QA person would give them the go ahead and they would again create a Pull Request for Production (master).
This is the same release cycle they use today.
In my new job, I have been assisting someone in the automation of their release cycles. I haven't been directly involved with every aspect of what he does but they have had problems that I've never seen before.
BTW, these teams deal with ksh and bash scripts for the most part.
So, I introduced the concept of the previously explained workflow which used feature branches created from the master branch. Then, merging them into each release branch for deployment. The difference here is, I designed a rapid release cycle for Development deployments using Bamboo/Bit Bucket that rsyncs the changes immediately to the target.
The difference in this development cycle is that they don't see their feature all the way to production. They will work on a script and deploy it to their UAT/Test server but it may never make it to production.
So, given that they may work on a file several times without it ever making it to production, which doesn't make sense, I told them that they need to check the file in development/UAT release branch to make sure they have the most recent change. If they don't, they will create a feature branch containing an outdated script that may be 3 months behind and cause problems with trying to merge changes in a script that doesn't have all the change history.
So, my solution was to create the feature branch from master and checkout the script from the Development release branch, commit and then start making changes and commit the new changes again. This has worked for me every single time I tested it.
However, they are coming up with strange problems. The biggest one I've seen is they will modify some files and try to merge their feature branch into the Development release branch. The build will fail, telling them there is a conflict with a file that they did not change at all. It doesn't make any sense that a completely untouched file would show a conflict. I was under the impression that version control only tracked changes made to files, not show conflicts with files that have not changed.
Anyway, I'm open to other suggestions on workflow ideas but you know my logic behind the workflow. Another group internal here uses cherry picking of commits to promote changes. They are always dealing with conflicts and is a nightmare for the people dealing with the deployments.