private async function genChangesetFromNativePatch()

in src/shipit/repo/ShipItRepoHG.php [299:342]


  private async function genChangesetFromNativePatch(
    string $revision,
    string $header,
    string $patch,
  ): Awaitable<ShipItChangeset> {
    $changeset = self::getChangesetFromExportedPatch($header, $patch);
    // we need to have plain diffs for each file, and rename/copy from
    // breaks this, and we can't turn it off in hg.
    //
    // for example, if the change to 'proprietary/foo.cpp' is removed,
    // but 'public/foo.cpp' is not, this breaks:
    //
    //   rename from proprietary/foo.cpp to public/foo.cpp
    //
    // If we have any matching files, re-create their diffs using git, which
    // will do full diffs for both sides of the copy/rename.
    $matches = Regex\every_match(
      $patch,
      re"/^(?:rename|copy) (?:from|to) (?<files>.+)$/m",
    );
    $has_rename_or_copy = Keyset\map($matches, $m ==> $m['files']);
    $has_mode_change = $changeset->getDiffs()
      |> Vec\filter(
        $$,
        $diff ==> Regex\matches($diff['body'], re"/^old mode/m"),
      )
      |> Keyset\map($$, $diff ==> $diff['path']);

    $needs_git = Keyset\union($has_rename_or_copy, $has_mode_change);

    if ($needs_git) {
      $diffs = Vec\filter(
        $changeset->getDiffs(),
        $diff ==> !C\contains($needs_git, $diff['path']),
      );
      $diffs = Vec\concat(
        $diffs,
        await $this->genMakeDiffsUsingGit($revision, $needs_git),
      );
      $changeset = $changeset->withDiffs($diffs);
    }

    return $changeset->withID($revision);
  }