Using git patch or how to live with your packages not updating
There’s a longstanding bug in react-native that has been active since 2018. Korean text is broken on iOS (especially if you move the input cursor to the beginning of the line)
https://github.com/facebook/react-native/issues/19339
Various fixes were merged and reverted over the years (they cause problems in some other places)
Recently (2022 – 4 years later), a better fix were merged into react-native’s main branch
https://github.com/facebook/react-native/pull/32523
However it’s still unclear when this will get released, and it will take even more time for us to upgrade react-native
In order to use this in our final product, we’ll need to patch react-native manually
- Download react-native normally via npm install
- Patch node_modules/react-native/Libraries/Text/TextInput/RCTBaseTexinputView.m
- Build the project
Generating the patch
Let’s download the react-native repository
git clone https://github.com/facebook/react-native.git
You’ll find that it take a veeery long time
Let’s just get the last 1,000 commits instead
git clone --depth 1000 https://github.com/facebook/react-native.git
Much faster!
Next, reset the branch to the commit we want to extract (You can get the commit ID from the pull request, look at the end)
git reset --hard 1a83dc36ce0af33ac7a3c311354fce4bfa5ba1a3
Next, generate the patch file
git format-patch -1 main Libraries/Text/TextInput/RCTBaseTextInputView.m
Explanation
- git format-patch: generate patch file
- -1: from last 1 commit
- main: from main branch
Libraries/Text/TextInput/RCTBaseTextInputView.m
: patch to the file, omit to generate patch for the whole commit
Applying the patch
A cursory search on the internet will give you some npm package that you should install to apply a patch file. However, most *nix environment have a tool called patch
already installed. We can utilize this
Let’s add some script to `package.json`:
"patch-3882": "patch -st -p1 -d node_modules/react-native < patches/3882-fix-reactnative-textinput.patch",
"pod": "pod-install",
"postinstall": "npm run patch-3882; npm run pod",
"postuninstall": "npm run patch-3882; npm run pod",
Explanation
- postinstall / postuninstall will run after each package installation with npm. This will ensure our version of react-native stays patched. Also this will work on your existing build pipelines
- patch-3882: name of your custom build action
- patch: the patch command
- -st: run silently, ignore errors, assume the best
- -p1: convert git’s format to patch format by truncating the first level of directory from the patch file
- -d: specify the working directory, in this case, react-native’s
- < patchfile: pipe the patchfile into the patch command, this is not an input parameter
Gotchas:
- don’t use “&&” to combine commands, use “;” if you are using Microsoft AppCenter to build your binaries. “&&” will give an “unexpected end of file” error due to the shell on the build agent