We only have 2-3 developers working on WordPress projects. Our git flow is very simplified with three key branches, development, staging, and production. Pushing to a key branch triggers an automatic build and deploy to the relevant remote server. Pushing to development branch builds and deploys to the development.mysite.org remote, etc.
We all work on development branch for simple stuff and bug fixes. For complex or experimental feature development we spin off feature branches from development, and merge them back into development when complete.
Dev teams tests internally on local and the dev remote. When it passes QA we move the release candidate to staging using git checkout staging; git pull; git merge development; git push. staging never gets any code that didn't first pass through development.
On the staging remote the client reviews the release candidate and denies or approves. If it's denied it goes back to development. If approved, we run release checklists and push code to production via git checkout production; git pull; git merge staging; git push. production should never receive any code that didn't first pass through staging. We push production releases about once per month per client.
The problem is that the above workflow has two irritating flaws — first, it generates a ton of local and remote merge commit messages that clutter the history making it hard to read. Second, it's possible to accidentally commit to the wrong branch which can cause all sorts of workflow problems.
Question 1: I want to switch from merging downstream branches to rebasing, but when I git checkout staging; git rebase development I get all sorts of merge errors from commits that happened months or years ago. Is this due to switching from merges to rebase? Would this be avoided if we merged every time?
I have no concerns about rewriting history on staging and production because we should never be pushing anything to those branches that did not go through the upstream branches.
Question 2: Can branches be set to never accept a push except that it's a merge or rebase from an upstream branch?
Question 3: AM I DOING IT ALL WRONG. I feel like I just don't grok the power of rebase. Our system works ok, but sometimes we're hit with hellish git issues and don't really understand why.