code: public synchronized boolean migrate(File dir, @CheckForNull File jenkinsHome) {
          if (load(dir)) {
              LOGGER.log(FINER, "migration already performed for {0}", dir);
              return false;
          }
          if (!dir.isDirectory()) {
              LOGGER.log(/* normal during Job.movedTo */FINE, "{0} was unexpectedly missing", dir);
              return false;
          }
          LOGGER.log(INFO, "Migrating build records in {0}", dir);
          doMigrate(dir);
          save(dir);
          if (jenkinsHome != null && offeredToUnmigrate.add(jenkinsHome))
              LOGGER.log(WARNING, "Build record migration (https://jenkins.io/redirect/build-record-migration) is one-way. If you need to downgrade Jenkins, run: {0}", getUnmigrationCommandLine(jenkinsHome));
          return true;
      }
docs: Perform one-time migration if this has not been done already.
  Where previously there would be a {@code 2014-01-02_03-04-05/build.xml} specifying {@code <number>99</number>} plus a symlink {@code 99 → 2014-01-02_03-04-05},
  after migration there will be just {@code 99/build.xml} specifying {@code <id>2014-01-02_03-04-05</id>} and {@code <timestamp>…</timestamp>} according to local time zone at time of migration.
  Newly created builds are untouched.
  Does not throw {@link IOException} since we make a best effort to migrate but do not consider it fatal to job loading if we cannot.
  @param dir as in {@link Job#getBuildDir}
  @param jenkinsHome root directory of Jenkins (for logging only)
  @return true if migration was performed