Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-native-git-upgrade changes nothing #12112

Closed
joIivier opened this issue Jan 29, 2017 · 22 comments
Closed

react-native-git-upgrade changes nothing #12112

joIivier opened this issue Jan 29, 2017 · 22 comments
Labels
Resolution: Fixed A PR that fixes this issue has been merged. Resolution: Locked This issue was locked by the bot.

Comments

@joIivier
Copy link

joIivier commented Jan 29, 2017

Description

I am trying to upgrade from react native 35 to 40. Running 'react-native-git-upgrade' in my project tells me the upgrade has been done but nothing has changed in my repository.

Output:

/usr/local/Cellar/node/7.4.0/bin/react-native-git-upgrade 
git-upgrade info Check for updates
git-upgrade info Using yarn 0.19.1
git-upgrade info Read package.json files
git-upgrade info Check declared version
git-upgrade info Check matching versions
git-upgrade info Check React peer dependency
git-upgrade info Check that Git is installed
git-upgrade info Get information from NPM registry
git-upgrade info Upgrading to React Native 0.40.0, React ~15.4.0-rc.4
git-upgrade info Setup temporary working directory
git-upgrade info Configure Git environment
git-upgrade info Init Git repository
git-upgrade info Add all files to commit
git-upgrade info Commit current project sources
git-upgrade info Create a tag before updating sources
git-upgrade info Generate old version template
git-upgrade info Add updated files to commit
git-upgrade info Commit old version template
git-upgrade info Install the new version
git-upgrade info Generate new version template
git-upgrade info Add updated files to commit
warning: CRLF will be replaced by LF in android/gradlew.bat.


The file will have its original line endings in your working directory.
git-upgrade info Commit new version template
git-upgrade info Generate the patch between the 2 versions
git-upgrade info Save the patch in temp directory
git-upgrade info Reset the 2 temporary commits
git-upgrade info Apply the patch
error: patch failed: .flowconfig:1
Falling back to three-way merge...
Applied patch to '.flowconfig' with conflicts.
error: patch failed: .gitignore:22
Falling back to three-way merge...
Applied patch to '.gitignore' with conflicts.
error: android/app/src/main/java/com/appname/MainApplication.java: does not exist in index
error: cannot apply binary patch to 'android/gradle/wrapper/gradle-wrapper.jar' without full index line
Falling back to three-way merge...
error: cannot apply binary patch to 'android/gradle/wrapper/gradle-wrapper.jar' without full index line
error: android/gradle/wrapper/gradle-wrapper.jar: patch does not apply
error: patch failed: ios/appname.xcodeproj/project.pbxproj:22
Falling back to three-way merge...
Applied patch to 'ios/appname.xcodeproj/project.pbxproj' with conflicts.
error: patch failed: ios/appname.xcodeproj/xcshareddata/xcschemes/appname.xcscheme:3
Falling back to three-way merge...
Applied patch to 'ios/appname.xcodeproj/xcshareddata/xcschemes/appname.xcscheme' cleanly.
error: ios/appname/AppDelegate.m: does not exist in index
error: patch failed: ios/appname/Info.plist:45
Falling back to three-way merge...
Applied patch to 'ios/appname/Info.plist' with conflicts.
git-upgrade WARN The upgrade process succeeded but there might be conflicts to be resolved. See above for the list of files that have merge conflicts.
git-upgrade info Upgrade done

Then I look in my status

git status
On branch migration-rn40-2
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	../../../old-logs

nothing added to commit but untracked files present (use "git add" to track)

Nothing. No conflict.
This is the ouptut after I ignored *.png in my global gitignore file (as per issue #11402). I had previously also warning related to the png files (although I never changed this part of the project since I'm only doing iOs for now).
After this script is run I get react native 40 in my node modules, but I couldn't build the project on Xcode which was complaining about the React native libraries of my project.

Solution

I guess the critical lines in the logs are the "without full index line" errors for the binaries I don't have (maybe because I never ran the android project) and the "does not exist in index" that is thrown for AppDelegate.m (I use swift instead).

I managed to get it to work by changing in cliEntry.js git apply --3way ${patchPath} by git apply --reject ${patchPath} which worked (I could start correctly my application afterwards) but I will have to merge manually the conflicts now.

I guess you should at least test the output code of git apply to detect a failure and print a valid error message, and maybe suggest to retry with --reset instead of --3way if the --3way failed.

Additional Information

  • React Native version: 35
  • Platform: iOs
  • Operating System: MacOS
@sibelius
Copy link

@joIivier how can I apply your patch locally?

@sibelius
Copy link

@ncuillery I have the same error from RN39 to RN41

@joIivier
Copy link
Author

@sibelius in cliEntry.js replace git apply --3way by git apply --reject, run the migration script again and merge manually the files that were rejected by git (files ending in .rej).

@sibelius
Copy link

I think it should run git apply --reject if git apply --3way fails

@dwilt
Copy link

dwilt commented Feb 18, 2017

This seems like a pretty basic thing for upgrading react native and I don't understand why more people aren't complaining about it. I've been unable to use this tool successfully and have reinstalled multiple times. Any updates here?

@dwilt
Copy link

dwilt commented Feb 21, 2017

@joIivier where in cliEntry.js are you seeing this? Here's mine:

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @flow
 */
'use strict';

const Config = require('./util/Config');

const assertRequiredOptions = require('./util/assertRequiredOptions');
const chalk = require('chalk');
const childProcess = require('child_process');
const commander = require('commander');
const commands = require('./commands');
const defaultConfig = require('./default.config');
const init = require('./init/init');
const minimist = require('minimist');
const path = require('path');
const pkg = require('../package.json');

import type {Command} from './commands';
import type {ConfigT} from './util/Config';

commander.version(pkg.version);

const defaultOptParser = (val) => val;

const handleError = (err) => {
  console.error();
  console.error(err.message || err);
  console.error();
  process.exit(1);
};

// Custom printHelpInformation command inspired by internal Commander.js
// one modified to suit our needs
function printHelpInformation() {
  let cmdName = this._name;
  if (this._alias) {
    cmdName = cmdName + '|' + this._alias;
  }

  const sourceInformation = this.pkg
    ? [
      `  ${chalk.bold('Source:')} ${this.pkg.name}@${this.pkg.version}`,
      '',
    ]
    : [];

  let output = [
    '',
    chalk.bold(chalk.cyan((`  react-native ${cmdName} ${this.usage()}`))),
    `  ${this._description}`,
    '',
    ...sourceInformation,
    `  ${chalk.bold('Options:')}`,
    '',
    this.optionHelp().replace(/^/gm, '    '),
    '',
  ];

  if (this.examples && this.examples.length > 0) {
    const formattedUsage = this.examples.map(
      example => `    ${example.desc}: \n    ${chalk.cyan(example.cmd)}`,
    ).join('\n\n');

    output = output.concat([
      chalk.bold('  Example usage:'),
      '',
      formattedUsage,
    ]);
  }

  return output.concat([
    '',
    '',
  ]).join('\n');
}

function printUnknownCommand(cmdName) {
  console.log([
    '',
    cmdName
      ? chalk.red(`  Unrecognized command '${cmdName}'`)
      : chalk.red('  You didn\'t pass any command'),
    `  Run ${chalk.cyan('react-native --help')} to see list of all available commands`,
    '',
  ].join('\n'));
}

const addCommand = (command: Command, config: ConfigT) => {
  const options = command.options || [];

  const cmd = commander
    .command(command.name, undefined, {
      noHelp: !command.description,
    })
    .description(command.description)
    .action(function runAction() {
      const passedOptions = this.opts();
      const argv: Array<string> = Array.from(arguments).slice(0, -1);

      Promise.resolve()
        .then(() => {
          assertRequiredOptions(options, passedOptions);
          return command.func(argv, config, passedOptions);
        })
        .catch(handleError);
    });

    cmd.helpInformation = printHelpInformation.bind(cmd);
    cmd.examples = command.examples;
    cmd.pkg = command.pkg;

  options
    .forEach(opt => cmd.option(
      opt.command,
      opt.description,
      opt.parse || defaultOptParser,
      typeof opt.default === 'function' ? opt.default(config) : opt.default,
    ));

  // Placeholder option for --config, which is parsed before any other option,
  // but needs to be here to avoid "unknown option" errors when specified
  cmd.option('--config [string]', 'Path to the CLI configuration file');
};

function getCliConfig() {
  // Use a lightweight option parser to look up the CLI configuration file,
  // which we need to set up the parser for the other args and options
  const cliArgs = minimist(process.argv.slice(2));

  let cwd;
  let configPath;
  if (cliArgs.config != null) {
    cwd = process.cwd();
    configPath = cliArgs.config;
  } else {
    cwd = __dirname;
    configPath = Config.findConfigPath(cwd);
  }

  return Config.get(cwd, defaultConfig, configPath);
}

function run() {
  const setupEnvScript = /^win/.test(process.platform)
    ? 'setup_env.bat'
    : 'setup_env.sh';

  childProcess.execFileSync(path.join(__dirname, setupEnvScript));

  const config = getCliConfig();
  commands.forEach(cmd => addCommand(cmd, config));

  commander.parse(process.argv);

  const isValidCommand = commands.find(cmd => cmd.name.split(' ')[0] === process.argv[2]);

  if (!isValidCommand) {
    printUnknownCommand(process.argv[2]);
    return;
  }

  if (!commander.args.length) {
    commander.help();
  }
}

module.exports = {
  run: run,
  init: init,
};

@dwilt
Copy link

dwilt commented Feb 21, 2017

@joIivier @ncuillery Made a video showing my struggles lol. Any suggestions here would be greatly appreciated as our current method of upgrading, completely manual, is a total PITA.

https://youtu.be/5BIsXChxAhk

@dwilt
Copy link

dwilt commented Feb 21, 2017

Just tried on a coworkers computer who is in the same repo as us and got the exact same results.

@sibelius
Copy link

@dwilt change this line: https://github.com/facebook/react-native/blob/master/react-native-git-upgrade/cliEntry.js#L331

@wangergou93
Copy link

wangergou93 commented Feb 27, 2017

Why my cliEntry.js doesn't the same to you i can't find the line @sibelius

@atticoos
Copy link
Contributor

atticoos commented Mar 6, 2017

I discovered that a .patch file containing the diffs exists in $TMPDIR/react-native-git-upgrade/upgrade_0.40.0_0.42.0.patch.

I took a look at this file, and sure enough, there's all my diffs.

So then I use git apply <path> --reject and it all works fine.

Working reproducible steps

  1. Inside your working directory, run react-native-git-upgrade
  2. Upon completion, ls $TMPDIR/react-native-git-upgrade -- you'll find your corresponding .patch file, the name will correspond to the versions you're upgrading between.
  3. Inside your working directory, run git apply <path to patch> --reject

@foggy1
Copy link

foggy1 commented Mar 22, 2017

Having this issue going from .40 to .42.3. On first try, merge conflicts registered in the proper files. But subsequent tries yielded no such luck and required the reject flag for any discernible conflict.

@christophermark
Copy link

What seems to cause this

This issue is reproducible when the diff between the React Native project template files have changed (between your current RN version and the newest RN version) in one of the following ways:

  • You've already updated a file which got updated by React Native
    • Most commonly found with Gradle version numbers in Android projects, where Android Studio will update this for you.
    • Say React Native has upgraded Gradle from 1.3.1 to 2.2.3, but you're already on 2.3.3. The patch will fail since it can't find the line with the gradle version as 1.3.1
  • There is a line removed in the RN template files which is not found in your project
    • Say they removed a commented line, but you had previously already removed it from your project file. It will fail since it cannot delete a line that's not there.

The core issue

As others have identified, the upgrade process creates a patch file, then tries to apply the patch. When it tries to apply a --3way patch, it will fail if it encounters any errors such as those above ☝️. Unfortunately, it reverses the whole patch when a 3-way patch fails to apply.

If you change the git strategy for applying the patch from --3way to --reject, it will allow your changes to go through, then you just have to resolve and remove the .rej files where it had errored out. You can either do this after it fails using the patch file @ajwhite found, or change the cliEntry.js directly as described in the PR description.

@sibelius and @whk1459086640, you should be looking for cliEntry.js inside the react-native-git-upgrade node_modules directory, found where NPM (globally) installed react-native-git-upgrade.

@dantman
Copy link
Contributor

dantman commented Apr 7, 2017

If you change the git strategy for applying the patch from --3way to --reject, it will allow your changes to go through, then you just have to resolve and remove the .rej files where it had errored out. You can either do this after it fails using the patch file @ajwhite found, or change the cliEntry.js directly as described in the PR description.

Upgrading shouldn't require finding a hidden temp file or editing a library file. The simplest workaround would probably be adding a cli argument to react-native-git-upgrade that will make the git command use --reject instead of --3way.

@foggy1
Copy link

foggy1 commented Apr 7, 2017

It seems like the patch should be agnostic as to the state of the thing needing to be upgraded, e.g. it should look to patch a version without caring about what the version number ought to have been previously. This is especially the case because both Android Studio and Xcode will upgrade native config stuff as needed, not to mention the need to manually upgrade specific lines as certain libraries might demand.

@AlanFoster
Copy link
Contributor

AlanFoster commented Jun 24, 2017

Running into this same problem on mac upgrading from react-native 0.43.3 to v0.44.3

git-upgrade info Install the new version
git-upgrade info Generate new version template
git-upgrade info Add updated files to commit
warning: CRLF will be replaced by LF in android/gradlew.bat.
The file will have its original line endings in your working directory.
git-upgrade info Commit new version template
git-upgrade info Generate the patch between the 2 versions
git-upgrade info Save the patch in temp directory
git-upgrade info Reset the 2 temporary commits
git-upgrade info Apply the patch
error: patch failed: .babelrc:1
Falling back to three-way merge...
Applied patch to '.babelrc' with conflicts.
error: patch failed: ios/pocket.xcodeproj/project.pbxproj:1196
Falling back to three-way merge...
Applied patch to 'ios/pocket.xcodeproj/project.pbxproj' with conflicts.
error: ios/pocketTests/pocketTests.m: does not exist in index

When running a git status only the gradle windows file is changed:

✗ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   android/gradlew.bat

no changes added to commit (use "git add" and/or "git commit -a")

Edit: Following the steps of #12112 (comment) worked for me

However i needed to apply some extra args to git apply run:

git apply --reject --whitespace=fix $TMPDIR/react-native-git-upgrade/upgrade_0.43.3_0.44.3.patch

@hramos
Copy link
Contributor

hramos commented Aug 31, 2017

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

@akshay2604
Copy link

This issue still persists

enthal added a commit to enthal/react-native that referenced this issue Dec 18, 2017
FIX facebook#12112

Per facebook#12112 (comment) :
"As others have identified, the upgrade process creates a patch file, then tries to apply the patch. When it tries to apply a --3way patch, it will fail if it encounters any errors such as those above ☝️. Unfortunately, it reverses the whole patch when a 3-way patch fails to apply.

If you change the git strategy for applying the patch from --3way to --reject, it will allow your changes to go through, then you just have to resolve and remove the .rej files where it had errored out. You can either do this after it fails using the patch file @ajwhite found, or change the cliEntry.js directly as described in the PR description."
@enthal
Copy link

enthal commented Dec 18, 2017

PR #17266

facebook-github-bot pushed a commit that referenced this issue Apr 12, 2018
Summary:
The upgrade script uses `git apply --3way`:

https://github.com/facebook/react-native/blob/4906f8d28cdbaf1b432494b473a4c61c1e193881/react-native-git-upgrade/cliEntry.js#L368-L369

If you've already upgraded something that React Native upgraded, this will silently fail. For example if you have already upgraded Gradle to the version available in the new version of React Native, the 3-way patch will fail. In this case, the upgraded version is installed into `node_modules` but `package.json` is not updated. More context, discussion, and information is in #12112 (comment).

Until a more robust solution is implemented, this PR proposes to mitigate the effects of the problem by informing the user of the possible issue and instructing them of a workaround.

In an affected project, I ran `react-native-git-upgrade` after applying my patch.

As expected, I now receive the following output:

![image](https://user-images.githubusercontent.com/789577/38165770-6209ac68-34de-11e8-9d96-7c782e9ef7ce.png)

After running the suggested command, `git status` now shows me the two rejections:

![image](https://user-images.githubusercontent.com/789577/38165796-d10ca7c8-34de-11e8-9037-8427513e3a84.png)

And I can now [manually apply](https://stackoverflow.com/a/28569128/1445366) these changes.

[CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Provide instructions for upgrading React Native when 3-way merges don't apply
Closes #18636

Differential Revision: D7603073

Pulled By: hramos

fbshipit-source-id: 32d387e1ee67d8b182d248c585cd33ba94808357
@iainbeeston
Copy link

Looks like this issue will be fixed (via more helpful error message) when 4fbd244 is released

bunnyc1986 pushed a commit to bunnyc1986/react-native that referenced this issue May 11, 2018
Summary:
The upgrade script uses `git apply --3way`:

https://github.com/facebook/react-native/blob/4906f8d28cdbaf1b432494b473a4c61c1e193881/react-native-git-upgrade/cliEntry.js#L368-L369

If you've already upgraded something that React Native upgraded, this will silently fail. For example if you have already upgraded Gradle to the version available in the new version of React Native, the 3-way patch will fail. In this case, the upgraded version is installed into `node_modules` but `package.json` is not updated. More context, discussion, and information is in facebook#12112 (comment).

Until a more robust solution is implemented, this PR proposes to mitigate the effects of the problem by informing the user of the possible issue and instructing them of a workaround.

In an affected project, I ran `react-native-git-upgrade` after applying my patch.

As expected, I now receive the following output:

![image](https://user-images.githubusercontent.com/789577/38165770-6209ac68-34de-11e8-9d96-7c782e9ef7ce.png)

After running the suggested command, `git status` now shows me the two rejections:

![image](https://user-images.githubusercontent.com/789577/38165796-d10ca7c8-34de-11e8-9037-8427513e3a84.png)

And I can now [manually apply](https://stackoverflow.com/a/28569128/1445366) these changes.

[CLI] [ENHANCEMENT] [react-native-git-upgrade/cliEntry.js] - Provide instructions for upgrading React Native when 3-way merges don't apply
Closes facebook#18636

Differential Revision: D7603073

Pulled By: hramos

fbshipit-source-id: 32d387e1ee67d8b182d248c585cd33ba94808357
@yalopov
Copy link

yalopov commented May 23, 2018

still happening

@hramos
Copy link
Contributor

hramos commented May 24, 2018

This is fixed in 4fbd244

@hramos hramos added the Resolution: Fixed A PR that fixes this issue has been merged. label May 24, 2018
@facebook facebook locked as resolved and limited conversation to collaborators May 24, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Aug 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Fixed A PR that fixes this issue has been merged. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

Successfully merging a pull request may close this issue.