Repository: dotnet/efcore
File: src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs (C#)

Code before:
    ///     Gets a sub-namespace.
    /// </summary>
    /// <param name="rootNamespace">The root namespace.</param>
    /// <param name="namespace">The full namespace.</param>
    /// <returns>The sub-namespace.</returns>
    protected virtual string GetSubNamespace(string? rootNamespace, string @namespace)
    {
        rootNamespace ??= string.Empty;

        return @namespace == rootNamespace
            ? string.Empty
            : @namespace.StartsWith(rootNamespace + '.', StringComparison.Ordinal)
                ? @namespace[(rootNamespace.Length + 1)..]
                : @namespace;
    }

    /// <summary>
    ///     Removes the previous migration.
    /// </summary>
    /// <param name="projectDir">The project's root directory.</param>
    /// <param name="rootNamespace">The project's root namespace.</param>
    /// <param name="force">Don't check to see if the migration has been applied to the database.</param>
    /// <param name="dryRun">If <see langword="true" />, then nothing is actually written to disk.</param>
    /// <returns>The removed migration files.</returns>
    public virtual MigrationFiles RemoveMigration(string projectDir, string rootNamespace, bool force, bool dryRun)
        => RemoveMigration(projectDir, rootNamespace, force, language: null, dryRun: dryRun, offline: false);

    /// <summary>
    ///     Removes the previous migration.
    /// </summary>
    /// <param name="projectDir">The project's root directory.</param>
    /// <param name="rootNamespace">The project's root namespace.</param>
    /// <param name="force">Don't check to see if the migration has been applied to the database.</param>
    /// <param name="language">The project's language.</param>
    /// <param name="dryRun">If <see langword="true" />, then nothing is actually written to disk.</param>
    /// <param name="offline">Remove the migration without connecting to the database.</param>
    /// <returns>The removed migration files.</returns>
    public virtual MigrationFiles RemoveMigration(
        string projectDir,
        string? rootNamespace,
        bool force,
        string? language,
        bool dryRun = false,
        bool offline = false)
    {
        var files = new MigrationFiles();

        var modelSnapshot = Dependencies.MigrationsAssembly.ModelSnapshot;
        if (modelSnapshot == null)
        {
            throw new OperationException(DesignStrings.NoSnapshot);

Review comment (suggestion):
The XML docs for the `force` parameter say “Don't check to see if the migration has been applied”, but the implementation actually checks whether the migration is applied and, when `force` is set, reverts the database before removing files. Please update the `force` parameter documentation here to match the actual behavior (and to align with `IMigrationsScaffolder`).

Code after:
    ///     Gets a sub-namespace.
    /// </summary>
    /// <param name="rootNamespace">The root namespace.</param>
    /// <param name="namespace">The full namespace.</param>
    /// <returns>The sub-namespace.</returns>
    protected virtual string GetSubNamespace(string? rootNamespace, string @namespace)
    {
        rootNamespace ??= string.Empty;

        return @namespace == rootNamespace
            ? string.Empty
            : @namespace.StartsWith(rootNamespace + '.', StringComparison.Ordinal)
                ? @namespace[(rootNamespace.Length + 1)..]
                : @namespace;
    }

    /// <summary>
    ///     Removes the previous migration.
    /// </summary>
    /// <param name="projectDir">The project's root directory.</param>
    /// <param name="rootNamespace">The project's root namespace.</param>
    /// <param name="force">Revert the migration if it has been applied to the database.</param>
    /// <param name="dryRun">If <see langword="true" />, then nothing is actually written to disk.</param>
    /// <returns>The removed migration files.</returns>
    public virtual MigrationFiles RemoveMigration(string projectDir, string rootNamespace, bool force, bool dryRun)
        => RemoveMigration(projectDir, rootNamespace, force, language: null, dryRun: dryRun, offline: false);

    /// <summary>
    ///     Removes the previous migration.
    /// </summary>
    /// <param name="projectDir">The project's root directory.</param>
    /// <param name="rootNamespace">The project's root namespace.</param>
    /// <param name="force">Revert the migration if it has been applied to the database.</param>
    /// <param name="language">The project's language.</param>
    /// <param name="dryRun">If <see langword="true" />, then nothing is actually written to disk.</param>
    /// <param name="offline">Remove the migration without connecting to the database.</param>
    /// <returns>The removed migration files.</returns>
    public virtual MigrationFiles RemoveMigration(
        string projectDir,
        string? rootNamespace,
        bool force,
        string? language,
        bool dryRun = false,
        bool offline = false)
    {
        var files = new MigrationFiles();

        var modelSnapshot = Dependencies.MigrationsAssembly.ModelSnapshot;
        if (modelSnapshot == null)
        {
            throw new OperationException(DesignStrings.NoSnapshot);