I know that there's plenty of similar questions, but I couldn't find a good answer that helps me to propose a good solution in the company where I work. We're not a lot of developers, but I would like to propose a scalable workflow.
The (not so) hypothetical case
The situation is the most common one: there is a master
branch that never receives direct commits. If I need to do something I create a feature/personal
branch (usually long-live personal branches was used more often than fats feature ones).
Once I feel comfortable with the code I created, I want to bring it back to master
(which, in meantime, has received another commits).
It's important to point up that both master
and branchX
are always pushed to remote.
So, to graphically clarify it, we are in this situation (I'll use C for commits, M for merges):
branch1 C2---C3---C6---C9---
/
master C0---C1---C4---C5---C7---C8
Current Workflow
The current used workflow can be defined merge-up/merge-down: since I don't want to fix merge conflicts in master, first I merge-up master
inside branch1
, and then I merge-down branch1
in master
.
branch1 C2---C3---C6---C9---M1
/ /\
master C0---C1---C4---C5---C7---C8 M2
Doing so, I resolve the conflict inside the branch and then I can merge down my branch into master.
Personally I don't like this solution for two main reasons:
- it leads to a very messy history tree
- merging a parent branch into a child branch sound so no-sense to me
On the other hand, my coworkers argues that:
- it's easy to understand, even for not-expert internship coworkers
- it leads to fewer errors since you left untouched the history (unlike rebase)
Proposed solution
What I proposed is the common and more straightforward rebase-before-merge-down workflow.
Once i want to merge branch1
in master
, first I rebase the former on the latter, so i handle all the conflicts in my branch; than I merge-down branch1
into master
(with NO-FF if the feature branch is meaningful, with FF otherwise)
branch1 C2---C3---C6
rebase / \
master C5---C7---C8 M1
This solution, however, has a main drawback:
Since both are synced with the remote, a
git push --force
is necessary. So, if someone do something wrong (because he's in a hurry, distracted or silly), weeks of work could be lost in one second.
On the other hand, the advantages should be:
- Keep the history tree very clean and meaningful
- Flatten and remove useless branches, keeping only relevant ones
So, the question?
Which scalable workflow do you adopt in your large team to keep the git history clean and meaningful, and, on the other side, prevent potential disasters like a wrong git push --force
can do?