diff --git a/go/cmd/dolt/commands/status.go b/go/cmd/dolt/commands/status.go index 740696be323..8aea69e70d4 100644 --- a/go/cmd/dolt/commands/status.go +++ b/go/cmd/dolt/commands/status.go @@ -46,8 +46,7 @@ type printData struct { stagedTables, unstagedTables, - untrackedTables, - filteredUntrackedTables map[string]string + untrackedTables map[string]string constraintViolationTables, dataConflictTables, @@ -178,7 +177,15 @@ func createPrintData(queryist cli.Queryist, sqlCtx *sql.Context, showIgnoredTabl return nil, err } - statusRows, err := cli.GetRowsForSql(queryist, sqlCtx, "select table_name,staged,status from dolt_status;") + var statusRows []sql.Row + var sqlQuery string + if showIgnoredTables { + sqlQuery = "select table_name,staged,status,ignored from dolt_status_ignored;" + } else { + sqlQuery = "select table_name,staged,status,ignored from dolt_status_ignored where ignored = false;" + } + statusRows, err = cli.GetRowsForSql(queryist, sqlCtx, sqlQuery) + if err != nil { return nil, err } @@ -197,28 +204,30 @@ func createPrintData(queryist cli.Queryist, sqlCtx *sql.Context, showIgnoredTabl tableName := row[0].(string) staged := row[1] status := row[2].(string) + ignored, err := GetTinyIntColAsBool(row[3]) + if err != nil { + return nil, err + } isStaged, err := GetTinyIntColAsBool(staged) if err != nil { return nil, err } - shouldIgnoreTable := false - if !isStaged { - // determine if the table should be ignored - ignored, err := ignorePatterns.IsTableNameIgnored(doltdb.TableName{Name: tableName}) + shouldIgnoreTable := ignored || doltdb.IsFullTextTable(tableName) + + if showIgnoredTables && shouldIgnoreTable { + ignoredTables.Ignore = append(ignoredTables.Ignore, doltdb.TableName{Name: tableName}) + } + + if !isStaged && !shouldIgnoreTable { + // Check for ignore conflicts even when not showing ignored tables + _, err := ignorePatterns.IsTableNameIgnored(doltdb.TableName{Name: tableName}) if conflict := doltdb.AsDoltIgnoreInConflict(err); conflict != nil { ignoredTables.Conflicts = append(ignoredTables.Conflicts, *conflict) } else if err != nil { return nil, err - } else if ignored == doltdb.DontIgnore { - ignoredTables.DontIgnore = append(ignoredTables.DontIgnore, doltdb.TableName{Name: tableName}) - } else if ignored == doltdb.Ignore { - ignoredTables.Ignore = append(ignoredTables.Ignore, doltdb.TableName{Name: tableName}) - } else { - return nil, fmt.Errorf("unrecognized ignore result value: %v", ignored) } - shouldIgnoreTable = ignored == doltdb.Ignore } shouldIgnoreTable = shouldIgnoreTable || doltdb.IsFullTextTable(tableName) @@ -269,25 +278,6 @@ func createPrintData(queryist cli.Queryist, sqlCtx *sql.Context, showIgnoredTabl } } - // filter out ignored tables from untracked tables - filteredUntrackedTables := map[string]string{} - for tableName, status := range untrackedTables { - ignored, err := ignorePatterns.IsTableNameIgnored(doltdb.TableName{Name: tableName}) - - if conflict := doltdb.AsDoltIgnoreInConflict(err); conflict != nil { - continue - } else if err != nil { - return nil, err - } else if ignored == doltdb.DontIgnore { - // no-op - } else if ignored == doltdb.Ignore { - continue - } else { - return nil, fmt.Errorf("unrecognized ignore result value: %v", ignored) - } - filteredUntrackedTables[tableName] = status - } - pd := printData{ branchName: branchName, remoteName: remoteName, @@ -300,7 +290,6 @@ func createPrintData(queryist cli.Queryist, sqlCtx *sql.Context, showIgnoredTabl stagedTables: stagedTables, unstagedTables: unstagedTables, untrackedTables: untrackedTables, - filteredUntrackedTables: filteredUntrackedTables, ignoredTables: ignoredTables, constraintViolationTables: constraintViolationTables, schemaConflictTables: schemaConflictTables, @@ -612,7 +601,7 @@ and have %v and %v different commits each, respectively. } cli.Println(untrackedHeader) cli.Println(untrackedHeaderHelp) - for tableName, status := range data.filteredUntrackedTables { + for tableName, status := range data.untrackedTables { text := fmt.Sprintf(statusFmt, status+":", tableName) redText := color.RedString(text) cli.Println(redText) diff --git a/go/libraries/doltcore/sqle/dtables/status_ignored_table.go b/go/libraries/doltcore/sqle/dtables/status_ignored_table.go index 402df8d980d..eee59b8403c 100644 --- a/go/libraries/doltcore/sqle/dtables/status_ignored_table.go +++ b/go/libraries/doltcore/sqle/dtables/status_ignored_table.go @@ -147,7 +147,8 @@ func newStatusIgnoredItr(ctx *sql.Context, st *StatusIgnoredTable) (*StatusIgnor if row.isStaged == byte(0) && row.status == newTableStatus && unstagedTableNames[row.tableName] { tblNameObj := doltdb.TableName{Name: row.tableName} result, err := ignorePatterns.IsTableNameIgnored(tblNameObj) - if err != nil { + // If a table name has conflicting ignore rules, don't ignore it. + if err != nil && doltdb.AsDoltIgnoreInConflict(err) == nil { return nil, err } if result == doltdb.Ignore { diff --git a/go/libraries/doltcore/sqle/dtables/status_table.go b/go/libraries/doltcore/sqle/dtables/status_table.go index de325486a3a..af053910612 100644 --- a/go/libraries/doltcore/sqle/dtables/status_table.go +++ b/go/libraries/doltcore/sqle/dtables/status_table.go @@ -265,12 +265,36 @@ func newStatusItr(ctx *sql.Context, st *StatusTable) (*StatusItr, error) { return &StatusItr{rows: nil}, nil } - rows, _, err := getStatusRowsData(ctx, st.rootsProvider, st.workingSet) + rows, unstagedTables, err := getStatusRowsData(ctx, st.rootsProvider, st.workingSet) if err != nil { return nil, err } - return &StatusItr{rows: rows}, nil + // Filter out ignored tables from the results. + // Unstaged new tables that match ignore patterns get filtered. + ignorePatterns, err := getIgnorePatterns(ctx, st.rootsProvider) + if err != nil { + return nil, err + } + + unstagedTableNames := buildUnstagedTableNameSet(unstagedTables) + + filteredRows := make([]statusTableRow, 0, len(rows)) + for _, row := range rows { + if row.isStaged == byte(0) && row.status == newTableStatus && unstagedTableNames[row.tableName] { + tblNameObj := doltdb.TableName{Name: row.tableName} + result, err := ignorePatterns.IsTableNameIgnored(tblNameObj) + if err != nil { + return nil, err + } + if result == doltdb.Ignore { + continue + } + } + filteredRows = append(filteredRows, row) + } + + return &StatusItr{rows: filteredRows}, nil } func schemaStatusString(sd diff.DatabaseSchemaDelta) string { diff --git a/go/libraries/doltcore/sqle/dtables/unscoped_diff_table.go b/go/libraries/doltcore/sqle/dtables/unscoped_diff_table.go index c41441797b2..2acad87a235 100644 --- a/go/libraries/doltcore/sqle/dtables/unscoped_diff_table.go +++ b/go/libraries/doltcore/sqle/dtables/unscoped_diff_table.go @@ -202,10 +202,19 @@ func (dt *UnscopedDiffTable) newWorkingSetRowItr(ctx *sql.Context) (sql.RowIter, return nil, err } + // Get ignore patterns to filter out ignored unstaged new tables + schemas := []string{doltdb.DefaultSchemaName} + ignorePatternMap, err := doltdb.GetIgnoredTablePatterns(ctx, roots, schemas) + if err != nil { + return nil, err + } + patterns := ignorePatternMap[doltdb.DefaultSchemaName] + var ri sql.RowIter ri = &doltDiffWorkingSetRowItr{ stagedTableDeltas: staged, unstagedTableDeltas: unstaged, + ignorePatterns: patterns, } for _, filter := range dt.partitionFilters { @@ -222,40 +231,57 @@ type doltDiffWorkingSetRowItr struct { unstagedTableDeltas []diff.TableDelta stagedIndex int unstagedIndex int + ignorePatterns doltdb.IgnorePatterns } func (d *doltDiffWorkingSetRowItr) Next(ctx *sql.Context) (sql.Row, error) { - var changeSet string - var tableDelta diff.TableDelta - if d.stagedIndex < len(d.stagedTableDeltas) { - changeSet = "STAGED" - tableDelta = d.stagedTableDeltas[d.stagedIndex] - d.stagedIndex++ - } else if d.unstagedIndex < len(d.unstagedTableDeltas) { - changeSet = "WORKING" - tableDelta = d.unstagedTableDeltas[d.unstagedIndex] - d.unstagedIndex++ - } else { - return nil, io.EOF - } - - change, err := tableDelta.GetSummary(ctx) - if err != nil { - return nil, err - } + for { + var changeSet string + var tableDelta diff.TableDelta + if d.stagedIndex < len(d.stagedTableDeltas) { + changeSet = "STAGED" + tableDelta = d.stagedTableDeltas[d.stagedIndex] + d.stagedIndex++ + } else if d.unstagedIndex < len(d.unstagedTableDeltas) { + changeSet = "WORKING" + tableDelta = d.unstagedTableDeltas[d.unstagedIndex] + d.unstagedIndex++ + } else { + return nil, io.EOF + } - sqlRow := sql.NewRow( - changeSet, - change.TableName.String(), - nil, // committer - nil, // email - nil, // date - nil, // message - change.DataChange, - change.SchemaChange, - ) + // Skip ignored unstaged new tables (same as Git behavior: + // only untracked/new tables can be ignored). + if changeSet == "WORKING" && tableDelta.IsAdd() { + tblName := doltdb.TableName{Name: tableDelta.CurName()} + result, err := d.ignorePatterns.IsTableNameIgnored(tblName) + // If a table name has conflicting ignore rules, don't ignore it. + if err != nil && doltdb.AsDoltIgnoreInConflict(err) == nil { + return nil, err + } + if result == doltdb.Ignore { + continue + } + } + + change, err := tableDelta.GetSummary(ctx) + if err != nil { + return nil, err + } - return sqlRow, nil + sqlRow := sql.NewRow( + changeSet, + change.TableName.String(), + nil, // committer + nil, // email + nil, // date + nil, // message + change.DataChange, + change.SchemaChange, + ) + + return sqlRow, nil + } } func (d *doltDiffWorkingSetRowItr) Close(c *sql.Context) error { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index b033d19f77a..f5039e03d13 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -7790,8 +7790,8 @@ var DoltCherryPickTests = []queries.ScriptTest{ }, { // An ignored table should still be present (and unstaged) after aborting the merge. - Query: "select * from dolt_status;", - Expected: []sql.Row{{"generated_foo", byte(0), "new table"}}, + Query: "select * from dolt_status_ignored;", + Expected: []sql.Row{{"generated_foo", byte(0), "new table", true}}, }, { // Changes made to the table during the merge should not be reverted. diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_revert.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_revert.go index 9daf2c1a65f..81cab3b5403 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_revert.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_revert.go @@ -134,8 +134,8 @@ var RevertScripts = []queries.ScriptTest{ ExpectedErrStr: "table not found: dont_track", }, { - Query: "select * from dolt_status", - Expected: []sql.Row{{"dont_track", byte(0), "new table"}}, + Query: "select * from dolt_status_ignored", + Expected: []sql.Row{{"dont_track", byte(0), "new table", true}}, }, }, }, diff --git a/integration-tests/bats/sql-diff.bats b/integration-tests/bats/sql-diff.bats index 72579392b29..ede7a1a5b9a 100644 --- a/integration-tests/bats/sql-diff.bats +++ b/integration-tests/bats/sql-diff.bats @@ -948,3 +948,21 @@ SQL [[ "$output" =~ "multiple values provided for \`skinny" ]] || false [ "$status" -eq 1 ] } + +@test "sql-diff: ignored tables in working set are skipped" { + dolt sql <