react-native/blog/2016-12-05-easy-upgrades-processed-by-git.md
Nicolas Cuillery 9c5efa34fb Announcement of react-native-git-upgrade
Summary:
Ping mkonicek

![fireshot capture 4 - easy upgrades relying on git_ - http___localhost_8079_react-native_](https://cloud.githubusercontent.com/assets/4425455/20825225/fe93bcb2-b862-11e6-8f0d-123ef2c9071f.png)
Closes https://github.com/facebook/react-native/pull/11263

Differential Revision: D4265603

Pulled By: mkonicek

fbshipit-source-id: 8e496f0d76536744f2b25848a974f240bb5fae3e
2016-12-02 11:58:36 -08:00

6.0 KiB

title author authorTitle authorURL authorImage authorTwitter category
Easy upgrades, relying on Git Nicolas Cuillery JavaScript consultant and trainer at Zenika https://twitter.com/ncuillery https://fr.gravatar.com/userimage/78328995/184460def705a160fd8edadc04f60eaf.jpg?size=128 ncuillery announcements

Each release of React Native may come with changes inside the iOS and Android sub-projects that you have to report in your project. This synchronisation has always been a major pain point because of the poor changes detection within your source files. Today, I'm proud to announce a new upgrading process relying on the most popular version control system: Git.

The key concept in this operation is the generation of a Git patch that contains all the changes required by React Native from your current version to the requested one.

To obtain this patch, we need to generate the iOS and Android apps from the templates embedded in the react-native package inside your node_modules directory, exactly like the init and upgrade commands do. Then, after the native apps have been computed from the templates in both current version and requested versions, Git is be able to produce a patch that is completely adapted to your project (i.e. with your app name):

[...]

diff --git a/ios/MyAwesomeApp/Info.plist b/ios/MyAwesomeApp/Info.plist
index e98ebb0..2fb6a11 100644
--- a/ios/MyAwesomeApp/Info.plist
+++ b/ios/MyAwesomeApp/Info.plist
@@ -45,7 +45,7 @@
 		<dict>
 			<key>localhost</key>
 			<dict>
-				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
+				<key>NSExceptionAllowsInsecureHTTPLoads</key>
 				<true/>
 			</dict>
 		</dict>
 		
[...]

All we need now is to apply this patch on your current source files. While the old process would have prompted you for any difference (even from a single character), Git is able to merge most of the changes automatically, fallback on a 3-way merge and eventually leave familiar conflict delimiters:

		13B07F951A680F5B00A75B9A /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
<<<<<<< ours
				CODE_SIGN_IDENTITY = "iPhone Developer";
				FRAMEWORK_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)/HockeySDK.embeddedframework",
					"$(PROJECT_DIR)/HockeySDK-iOS/HockeySDK.embeddedframework",
				);
=======
				CURRENT_PROJECT_VERSION = 1;
>>>>>>> theirs
				HEADER_SEARCH_PATHS = (
					"$(inherited)",
					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
					"$(SRCROOT)/../node_modules/react-native/React/**",
					"$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**",
				);

These conflicts are generally easy to reason about. The delimiter ours actually stands for "your team" whereas their could be seen as "the React Native team".

Usage

As I mentioned in the Upgrading guide, the most important change concerns the automatic installation of the new react-native package.

You should not install the new react-native package by yourself, the upgrading process needs to be initiated on your current version of React Native. Otherwise, the current and requested versions would be the same, Git would produce an empty patch and the upgrade would be ineffective.

Install the react-native-git-upgrade package globally:

$ npm install -g react-native-git-upgrade

Then, run the react-native-git-upgrade command with an optional version (latest if not specified) inside your project directory:

Git needs to be available in the PATH.

Note that this new upgrade method aims at preserving your changes in your native files, so you don't need to run react-native link after an upgrade.

I have designed the implementation to be as less intrusive as possible. It is entirely based on a local Git repository created on-the-fly in the system temporary directory. It won't interfere with your project repository (no matter the VCS you use: Git, SVN, Mercurial, ... or none). Your sources are restored in case of unexpected errors.

Why a separated package ?

React Native comes with a global CLI (the react-native-cli package) which delegates the command to the local CLI embedded in the node_modules/react-native/local-cli directory.

As I mentioned above, the process has to be started upon your current React Native version. If we had embedded the implementation in the local-cli, you wouldn't have been able to enjoy this feature until the upcoming React Native release was in use on your project.

This Git upgrading feature is a huge improvement in developer experience and I really wanted it to be available for any users including those who are stuck in old versions of React Native (who said 0.28 ?) because of the painful upgrading process. That's why we came with the react-native-git-upgrade package, installed globally, no matter the version of React Native being used.

An other reason is the recent Yeoman wipeout by Martin Konicek. We didn't want to get these Yeoman dependencies back into the react-native package !

About the future

The standalone package is a temporary situation for a few months, it would probably never see the 1.0.0 release: when most users will have migrated their projects to the post-Yeoman era using this package, it will replace the actual react-native upgrade and the global package react-native-git-upgrade will be deprecated.

As a conclusion, I would say, enjoy the feature and feel free to suggest improvements, report issues and send pull requests. Each user has its own runtime environment, each React Native project is different, so we need you to make this process completely reliable and universal !