private void restoreRegion(final RegionInfo regionInfo,
    final SnapshotRegionManifest regionManifest, Path regionDir) throws IOException {
    Map<String, List<SnapshotRegionManifest.StoreFile>> snapshotFiles =
      getRegionHFileReferences(regionManifest);

    String tableName = tableDesc.getTableName().getNameAsString();
    final String snapshotName = snapshotDesc.getName();

    Path regionPath = new Path(tableDir, regionInfo.getEncodedName());
    HRegionFileSystem regionFS = (fs.exists(regionPath))
      ? HRegionFileSystem.openRegionFromFileSystem(conf, fs, tableDir, regionInfo, false)
      : HRegionFileSystem.createRegionOnFileSystem(conf, fs, tableDir, regionInfo);

    // Restore families present in the table
    for (Path familyDir : FSUtils.getFamilyDirs(fs, regionDir)) {
      byte[] family = Bytes.toBytes(familyDir.getName());

      StoreFileTracker tracker = StoreFileTrackerFactory.create(conf, true,
        StoreContext.getBuilder().withColumnFamilyDescriptor(tableDesc.getColumnFamily(family))
          .withFamilyStoreDirectoryPath(familyDir).withRegionFileSystem(regionFS).build());
      Set<String> familyFiles = getTableRegionFamilyFiles(familyDir);
      List<SnapshotRegionManifest.StoreFile> snapshotFamilyFiles =
        snapshotFiles.remove(familyDir.getName());
      List<StoreFileInfo> filesToTrack = new ArrayList<>();
      if (snapshotFamilyFiles != null) {
        List<SnapshotRegionManifest.StoreFile> hfilesToAdd = new ArrayList<>();
        for (SnapshotRegionManifest.StoreFile storeFile : snapshotFamilyFiles) {
          if (familyFiles.contains(storeFile.getName())) {
            // HFile already present
            familyFiles.remove(storeFile.getName());
            // no need to restore already present files, but we need to add those to tracker
            filesToTrack
              .add(tracker.getStoreFileInfo(new Path(familyDir, storeFile.getName()), true));
          } else {
            // HFile missing
            hfilesToAdd.add(storeFile);
          }
        }

        // Remove hfiles not present in the snapshot
        for (String hfileName : familyFiles) {
          Path hfile = new Path(familyDir, hfileName);
          if (!fs.getFileStatus(hfile).isDirectory()) {
            LOG.trace("Removing HFile=" + hfileName + " not present in snapshot=" + snapshotName
              + " from region=" + regionInfo.getEncodedName() + " table=" + tableName);
            HFileArchiver.archiveStoreFile(conf, fs, regionInfo, tableDir, family, hfile);
          }
        }

        // Restore Missing files
        for (SnapshotRegionManifest.StoreFile storeFile : hfilesToAdd) {
          LOG.debug("Restoring missing HFileLink " + storeFile.getName() + " of snapshot="
            + snapshotName + " to region=" + regionInfo.getEncodedName() + " table=" + tableName);
          String fileName =
            restoreStoreFile(familyDir, regionInfo, storeFile, createBackRefs, tracker);
          // mark the reference file to be added to tracker
          filesToTrack.add(tracker.getStoreFileInfo(new Path(familyDir, fileName), true));
        }
      } else {
        // Family doesn't exists in the snapshot
        LOG.trace("Removing family=" + Bytes.toString(family) + " in snapshot=" + snapshotName
          + " from region=" + regionInfo.getEncodedName() + " table=" + tableName);
        HFileArchiver.archiveFamilyByFamilyDir(fs, conf, regionInfo, familyDir, family);
        fs.delete(familyDir, true);
      }

      // simply reset list of tracked files with the matching files
      // and the extra one present in the snapshot
      tracker.set(filesToTrack);
    }

    // Add families not present in the table
    for (Map.Entry<String, List<SnapshotRegionManifest.StoreFile>> familyEntry : snapshotFiles
      .entrySet()) {
      Path familyDir = new Path(regionDir, familyEntry.getKey());
      StoreFileTracker tracker =
        StoreFileTrackerFactory.create(conf, true, StoreContext.getBuilder()
          .withFamilyStoreDirectoryPath(familyDir).withRegionFileSystem(regionFS).build());
      List<StoreFileInfo> files = new ArrayList<>();
      if (!fs.mkdirs(familyDir)) {
        throw new IOException("Unable to create familyDir=" + familyDir);
      }

      for (SnapshotRegionManifest.StoreFile storeFile : familyEntry.getValue()) {
        LOG.trace("Adding HFileLink (Not present in the table) " + storeFile.getName()
          + " of snapshot " + snapshotName + " to table=" + tableName);
        String fileName =
          restoreStoreFile(familyDir, regionInfo, storeFile, createBackRefs, tracker);
        files.add(tracker.getStoreFileInfo(new Path(familyDir, fileName), true));
      }
      tracker.set(files);
    }
  }
Restore region by removing files not in the snapshot and adding the missing ones from the
snapshot.
hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/RestoreSnapshotHelper.java