Someone merged in prettier formatting changes across the whole codebase into our master/main/develop
branch.
I am now trying to rebase against latest master/main/develop
branch, and resolve merge conflicts.
Since the conflicts are simply caused by running prettier to format code, is there a way to resolve conflicts automatically while preserving commit history? (no new merge commits, no extra formatting commits)
ProTip™️ Ensure all TeamMates have resolved conflicts for all WIP branches before the prettier mass formatting changes are merged! ✨
Once everyone resolved conflicts for their WIP branches ✅
Merge the prettier formatting changes on latest master 🙏
Come back here to auto-resolve formatting conflicts! 😁
Ensure you have the NEW version of prettier installed in your node_modules
:
git checkout master
git pull
yarn install
git checkout $FEATURE_BRANCH
Now, go to your master branch, and find two commit shas, put this in a notepad:
# 1. Commit where mass formatting was applied:
export MASS_FORMAT=0r93y82q9afuwiehojpei90ur38qy2huia
# 2. Commit just before that one (with updated prettier version + settings, etc):
export BEFORE_MASS_FORMAT=0ury810r8y32hquofawjp08hru3o2wafij
If you are certain the answer is "no" you can skip step 1.
To be extra safe, and gain experience with rebasing, just do step 1.
Additionally, look at the history on your $FEATURE_BRANCH
, and determine the last sha from master that is in your feature branch. This is called the "fork point" or "merge base", I'll refer to this sha as the $BASE_SHA
. (The first commit of your PR is the branches "FOOT
", as opposed to your branches HEAD
. Just before FOOT
would be your $BASE_SHA
.)
Rebase one: Ensure no conflicts before mass formatting changes were applied:
git checkout $FEATURE_BRANCH
git rebase --onto $BEFORE_MASS_FORMAT $BASE_SHA
Resolve conflicts throughout the rebase normally.
FEATURE_BRANCH=`git branch --show-current`
git checkout $MASS_FORMAT &&
git pull &&
yarn install && # pickup new prettier version
git checkout $FEATURE_BRANCH &&
git rebase \
--strategy-option theirs \ # This is flipped, means "keep my feature branch changes"
--empty=drop \ # Probably related to formatting.
--exec "$(echo \
'yarn prettier --write ' \
'package.json ' \
'$(git diff HEAD^..HEAD --name-only) ' \
'|| echo prettier failed its ok; ' \
'git add . ' \
' && git commit --amend --no-verify --no-edit' \
)" \
--onto $MASS_FORMAT $BEFORE_MASS_FORMAT;
package.json is listed in the --exec call, so that prettier won't decide to just format all files.
git pull origin master:master --rebase
If you are weary about force pushing, inspect diff:
git diff origin/$FEATURE_BRANCH
If the diff is too big and include unrelated changes from master... you can use range-diff:
git range-diff $BASE_SHA..origin/$FEATURE_BRANCH $BASE_SHA..$FEATURE_BRANCH
And lastly, push up cleanly formatted history:
git push --force-if-includes --force-with-lease origin master:master