Most of the teams I've worked on in the past have followed the same workflow when using Git (with some tiny variations):
develop
branch (git checkout develop
)git checkout -b feature/XYZ-123
)git add . && git commit -m "some commit message"
), then check develop
back out, pull it (git checkout develop && git pull
)develop
into it (git checkout feature/XYZ-123 && git merge develop
)git push -u origin feature/XYZ-123
) and create a PRWe'll call this the "Merge Method". The benefits are that any changes to develop
since you created the branch are now merged into your branch. And so by the time you create a PR, there are no merge conflicts with develop
and the code reviewers can see a clean, conflict-free diff between your branch and develop
.
I am now working on a team that has a similar flow up until the merge step, but then instead of merging develop
into my feature branch, they ask for a rebase from origin/develop
. So the actual steps are:
git checkout develop
git checkout -b feature/XYZ-123
git add . && git commit -m "some commit message"
git checkout develop && git pull
git checkout feature/XYZ-123
origin/dev
git push -u origin feature/XYZ-123
We'll call this the "Rebase Method". It too produces merge conflict-free PRs, but obviously it must have different pros/cons from the Merge Method explained up above.
I'm wondering what those pros/cons are. What does the Merge Method lend itself to that the Rebase Method lacks, and vice versa? When should one method be used as opposed to the other?
but obviously it must have different pros/cons from the Merge Method explained up above
Not really. Between reverse merging (as I call it) and rebasing, it's exactly the same effect in the end, namely to try to pick up all the most recent changes from develop
so that (1) the feature branch can be tested accurately and (2) the chances of a merge conflict when merging into develop
are reduced.
The main visible difference between reverse merging and rebasing is the lack of the extra merge commit on the feature branch. That makes rebasing appealing. So:
develop
.But here are some counterclaims:
If there's an incoming conflict, rebasing makes it harder to resolve those conflicts.
You can't rebase after pushing to form the pull request, because that rewrites shared history; whereas you can reverse merge at any time.
Personally I use both! I rebase just before the initial push to form the pull request; if the pull request lives a long time, I reverse merge periodically, and especially just before the actual approval and merge.