mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-28 18:59:00 -06:00
Merge pull request #6826 from dolthub/nicktobey/versionedtable
Support `AS OF` with `dolt_ignore` table.
This commit is contained in:
@@ -275,28 +275,18 @@ func (db Database) GetTableInsensitiveAsOf(ctx *sql.Context, tableName string, a
|
||||
return table, ok, nil
|
||||
}
|
||||
|
||||
switch table := table.(type) {
|
||||
case *DoltTable:
|
||||
tbl, err := table.LockedToRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return tbl, true, nil
|
||||
case *AlterableDoltTable:
|
||||
tbl, err := table.LockedToRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return tbl, true, nil
|
||||
case *WritableDoltTable:
|
||||
tbl, err := table.LockedToRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return tbl, true, nil
|
||||
default:
|
||||
versionableTable, ok := table.(dtables.VersionableTable)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("unexpected table type %T", table))
|
||||
}
|
||||
|
||||
versionedTable, err := versionableTable.LockedToRoot(ctx, root)
|
||||
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return versionedTable, true, nil
|
||||
|
||||
}
|
||||
|
||||
func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds *dsess.DoltSession, root *doltdb.RootValue, tblName string) (sql.Table, bool, error) {
|
||||
@@ -457,7 +447,12 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
dt, found = dtables.NewIgnoreTable(ctx, db.ddb, backingTable), true
|
||||
if backingTable == nil {
|
||||
dt, found = dtables.NewEmptyIgnoreTable(ctx), true
|
||||
} else {
|
||||
versionableTable := backingTable.(dtables.VersionableTable)
|
||||
dt, found = dtables.NewIgnoreTable(ctx, versionableTable), true
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
|
||||
@@ -38,8 +38,7 @@ var _ sql.ReplaceableTable = (*IgnoreTable)(nil)
|
||||
|
||||
// IgnoreTable is the system table that stores patterns for table names that should not be committed.
|
||||
type IgnoreTable struct {
|
||||
ddb *doltdb.DoltDB
|
||||
backingTable sql.Table
|
||||
backingTable VersionableTable
|
||||
}
|
||||
|
||||
func (i *IgnoreTable) Name() string {
|
||||
@@ -81,8 +80,13 @@ func (i *IgnoreTable) PartitionRows(context *sql.Context, partition sql.Partitio
|
||||
}
|
||||
|
||||
// NewIgnoreTable creates an IgnoreTable
|
||||
func NewIgnoreTable(_ *sql.Context, ddb *doltdb.DoltDB, backingTable sql.Table) sql.Table {
|
||||
return &IgnoreTable{ddb: ddb, backingTable: backingTable}
|
||||
func NewIgnoreTable(_ *sql.Context, backingTable VersionableTable) sql.Table {
|
||||
return &IgnoreTable{backingTable: backingTable}
|
||||
}
|
||||
|
||||
// NewEmptyIgnoreTable creates an IgnoreTable
|
||||
func NewEmptyIgnoreTable(_ *sql.Context) sql.Table {
|
||||
return &IgnoreTable{}
|
||||
}
|
||||
|
||||
// Replacer returns a RowReplacer for this table. The RowReplacer will have Insert and optionally Delete called once
|
||||
@@ -109,6 +113,24 @@ func (it *IgnoreTable) Deleter(*sql.Context) sql.RowDeleter {
|
||||
return newIgnoreWriter(it)
|
||||
}
|
||||
|
||||
func (it *IgnoreTable) LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (sql.IndexAddressableTable, error) {
|
||||
if it.backingTable == nil {
|
||||
return it, nil
|
||||
}
|
||||
return it.backingTable.LockedToRoot(ctx, root)
|
||||
}
|
||||
|
||||
// IndexedAccess implements IndexAddressableTable, but IgnoreTables has no indexes.
|
||||
// Thus, this should never be called.
|
||||
func (it *IgnoreTable) IndexedAccess(lookup sql.IndexLookup) sql.IndexedTable {
|
||||
panic("Unreachable")
|
||||
}
|
||||
|
||||
// GetIndexes implements IndexAddressableTable, but IgnoreTables has no indexes.
|
||||
func (it *IgnoreTable) GetIndexes(ctx *sql.Context) ([]sql.Index, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var _ sql.RowReplacer = (*ignoreWriter)(nil)
|
||||
var _ sql.RowUpdater = (*ignoreWriter)(nil)
|
||||
var _ sql.RowInserter = (*ignoreWriter)(nil)
|
||||
|
||||
27
go/libraries/doltcore/sqle/dtables/versioned_table.go
Normal file
27
go/libraries/doltcore/sqle/dtables/versioned_table.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2023 Dolthub, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package dtables
|
||||
|
||||
import (
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
)
|
||||
|
||||
// VersionableTable is a sql.Table that has a history. The history can be queried by setting a specific doltdb.RootValue.
|
||||
type VersionableTable interface {
|
||||
sql.Table
|
||||
LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (sql.IndexAddressableTable, error)
|
||||
}
|
||||
@@ -489,7 +489,7 @@ func newRowItrForTableAtCommit(ctx *sql.Context, table *DoltTable, h hash.Hash,
|
||||
return &historyIter{nonExistentTable: true}, nil
|
||||
}
|
||||
|
||||
table, err = table.LockedToRoot(ctx, root)
|
||||
lockedTable, err := table.LockedToRoot(ctx, root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -497,13 +497,13 @@ func newRowItrForTableAtCommit(ctx *sql.Context, table *DoltTable, h hash.Hash,
|
||||
var partIter sql.PartitionIter
|
||||
var histTable sql.Table
|
||||
if !lookup.IsEmpty() {
|
||||
indexes, err := table.GetIndexes(ctx)
|
||||
indexes, err := lockedTable.GetIndexes(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, idx := range indexes {
|
||||
if idx.ID() == lookup.Index.ID() {
|
||||
histTable = table.IndexedAccess(lookup)
|
||||
histTable = lockedTable.IndexedAccess(lookup)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -520,14 +520,14 @@ func newRowItrForTableAtCommit(ctx *sql.Context, table *DoltTable, h hash.Hash,
|
||||
}
|
||||
}
|
||||
if histTable == nil {
|
||||
histTable = table
|
||||
partIter, err = table.Partitions(ctx)
|
||||
histTable = lockedTable
|
||||
partIter, err = lockedTable.Partitions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
converter := rowConverter(table.Schema(), targetSchema, h, meta, projections)
|
||||
converter := rowConverter(lockedTable.Schema(), targetSchema, h, meta, projections)
|
||||
return &historyIter{
|
||||
table: histTable,
|
||||
tablePartitions: partIter,
|
||||
|
||||
@@ -39,6 +39,7 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/index"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/writer"
|
||||
@@ -74,6 +75,8 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
var _ dtables.VersionableTable = (*DoltTable)(nil)
|
||||
|
||||
// DoltTable implements the sql.Table interface and gives access to dolt table rows and schema.
|
||||
type DoltTable struct {
|
||||
tableName string
|
||||
@@ -120,7 +123,7 @@ func NewDoltTable(name string, sch schema.Schema, tbl *doltdb.Table, db dsess.Sq
|
||||
// LockedToRoot returns a version of this table with its root value locked to the given value. The table's values will
|
||||
// not change as the session's root value changes. Appropriate for AS OF queries, or other use cases where the table's
|
||||
// values should not change throughout execution of a session.
|
||||
func (t *DoltTable) LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (*DoltTable, error) {
|
||||
func (t *DoltTable) LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (sql.IndexAddressableTable, error) {
|
||||
tbl, ok, err := root.GetTable(ctx, t.tableName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -63,325 +63,64 @@ get_conflict_tables() {
|
||||
'
|
||||
}
|
||||
|
||||
@test "ignore: simple matches" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
CREATE TABLE dontignore (pk int);
|
||||
CREATE TABLE nomatch (pk int);
|
||||
SQL
|
||||
|
||||
dolt add -A
|
||||
@test "ignore: allow using dolt_ignore with AS OF" {
|
||||
|
||||
staged=$(get_staged_tables)
|
||||
ignored=$(get_ignored_tables)
|
||||
dolt branch start
|
||||
|
||||
[[ ! -z $(echo "$ignored" | grep "ignoreme") ]] || false
|
||||
[[ ! -z $(echo "$staged" | grep "dontignore") ]] || false
|
||||
[[ ! -z $(echo "$staged" | grep "nomatch") ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: specific overrides" {
|
||||
dolt sql -q "INSERT INTO dolt_ignore VALUES ('dolt_ignore', false)"
|
||||
dolt sql -q "INSERT INTO dolt_ignore VALUES ('test1', true)"
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE please_ignore (pk int);
|
||||
CREATE TABLE please_ignore_too (pk int);
|
||||
CREATE TABLE do_not_ignore (pk int);
|
||||
CREATE TABLE commit_me (pk int);
|
||||
CREATE TABLE commit_me_not(pk int);
|
||||
SQL
|
||||
dolt add dolt_ignore
|
||||
dolt commit -m "Insert into dolt_ignore"
|
||||
|
||||
dolt add -A
|
||||
dolt sql -q "INSERT INTO dolt_ignore VALUES ('test2', true)"
|
||||
dolt add dolt_ignore
|
||||
|
||||
ignored=$(get_ignored_tables)
|
||||
staged=$(get_staged_tables)
|
||||
dolt sql -q "INSERT INTO dolt_ignore VALUES ('test3', true)"
|
||||
|
||||
[[ ! -z $(echo "$ignored" | grep "please_ignore") ]] || false
|
||||
[[ ! -z $(echo "$ignored" | grep "please_ignore_too") ]] || false
|
||||
[[ ! -z $(echo "$staged" | grep "do_not_ignore") ]] || false
|
||||
[[ ! -z $(echo "$staged" | grep "commit_me") ]] || false
|
||||
[[ ! -z $(echo "$ignored" | grep "commit_me_not") ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: conflict" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE commit_ignore (pk int);
|
||||
SQL
|
||||
|
||||
run dolt add -A
|
||||
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ "the table commit_ignore matches conflicting patterns in dolt_ignore" ]] || false
|
||||
[[ "$output" =~ "ignored: *_ignore" ]] || false
|
||||
[[ "$output" =~ "not ignored: commit_*" ]] || false
|
||||
|
||||
}
|
||||
|
||||
@test "ignore: question mark" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE test (pk int);
|
||||
CREATE TABLE test1 (pk int);
|
||||
CREATE TABLE test11 (pk int);
|
||||
SQL
|
||||
|
||||
dolt add -A
|
||||
|
||||
ignored=$(get_ignored_tables)
|
||||
staged=$(get_staged_tables)
|
||||
|
||||
[[ ! -z $(echo "$ignored" | grep "test$") ]] || false
|
||||
[[ ! -z $(echo "$ignored" | grep "test1$") ]] || false
|
||||
[[ ! -z $(echo "$staged" | grep "test11$") ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: don't stash ignored tables" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
SQL
|
||||
|
||||
run dolt stash -u
|
||||
run dolt sql -q "SELECT * FROM dolt_ignore AS OF 'WORKING'"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "No local changes to save" ]] || false
|
||||
}
|
||||
[[ "$output" =~ "test1" ]] || false
|
||||
[[ "$output" =~ "test2" ]] || false
|
||||
[[ "$output" =~ "test3" ]] || false
|
||||
|
||||
@test "ignore: error when trying to stash table with dolt_ignore conflict" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE commit_ignore (pk int);
|
||||
SQL
|
||||
|
||||
run dolt stash -u
|
||||
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ "the table commit_ignore matches conflicting patterns in dolt_ignore" ]] || false
|
||||
[[ "$output" =~ "ignored: *_ignore" ]] || false
|
||||
[[ "$output" =~ "not ignored: commit_*" ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: stash ignored and untracked tables when --all is passed" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
CREATE TABLE dontignore (pk int);
|
||||
SQL
|
||||
|
||||
dolt stash -a
|
||||
|
||||
working=$(get_working_tables)
|
||||
ignored=$(get_ignored_tables)
|
||||
|
||||
[[ -z $(echo "$ignored" | grep "ignoreme") ]] || false
|
||||
[[ -z $(echo "$working" | grep "dontignore") ]] || false
|
||||
|
||||
dolt stash pop
|
||||
|
||||
working=$(get_working_tables)
|
||||
ignored=$(get_ignored_tables)
|
||||
|
||||
[[ ! -z $(echo "$ignored" | grep "ignoreme") ]] || false
|
||||
[[ ! -z $(echo "$working" | grep "dontignore") ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: stash table with dolt_ignore conflict when --all is passed" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE commit_ignore (pk int);
|
||||
SQL
|
||||
|
||||
dolt stash -a
|
||||
|
||||
conflicts=$(get_conflict_tables)
|
||||
|
||||
[[ -z $(echo "$conflicts" | grep "commit_ignore") ]] || false
|
||||
|
||||
dolt stash pop
|
||||
|
||||
conflicts=$(get_conflict_tables)
|
||||
|
||||
[[ ! -z $(echo "$conflicts" | grep "commit_ignore") ]] || false
|
||||
|
||||
}
|
||||
|
||||
@test "ignore: allow staging ignored tables if 'add --force' is supplied" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
SQL
|
||||
|
||||
dolt add -A --force
|
||||
|
||||
staged=$(get_staged_tables)
|
||||
|
||||
[[ ! -z $(echo "$staged" | grep "ignoreme") ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: don't auto-stage ignored tables" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
CREATE TABLE nomatch (pk int);
|
||||
SQL
|
||||
|
||||
dolt commit -m "commit1" -A
|
||||
|
||||
run dolt show
|
||||
run dolt sql -q "SELECT * FROM dolt_ignore AS OF 'STAGED'"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "test1" ]] || false
|
||||
[[ "$output" =~ "test2" ]] || false
|
||||
[[ ! "$output" =~ "test3" ]] || false
|
||||
|
||||
! [["$output" =~ "diff --dolt a/ignoreme b/ignoreme"]] || false
|
||||
|
||||
}
|
||||
|
||||
@test "ignore: dolt status doesn't show ignored tables when --ignored is not supplied" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
CREATE TABLE nomatch (pk int);
|
||||
SQL
|
||||
|
||||
run dolt status
|
||||
run dolt sql -q "SELECT * FROM dolt_ignore AS OF 'HEAD'"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "test1" ]] || false
|
||||
[[ ! "$output" =~ "test2" ]] || false
|
||||
[[ ! "$output" =~ "test3" ]] || false
|
||||
|
||||
[[ "$output" =~ "nomatch" ]] || false
|
||||
! [["$output" =~ "Ignored tables"]] || false
|
||||
! [["$output" =~ "ignoreme"]] || false
|
||||
|
||||
}
|
||||
|
||||
@test "ignore: dolt status shows ignored tables when --ignored is not supplied" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
CREATE TABLE nomatch (pk int);
|
||||
SQL
|
||||
|
||||
run dolt status --ignored
|
||||
run dolt sql -q "SELECT * FROM dolt_ignore AS OF 'main'"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "test1" ]] || false
|
||||
[[ ! "$output" =~ "test2" ]] || false
|
||||
[[ ! "$output" =~ "test3" ]] || false
|
||||
|
||||
[[ "$output" =~ "nomatch" ]] || false
|
||||
[[ "$output" =~ "Ignored tables" ]] || false
|
||||
[[ "$output" =~ "ignoreme" ]] || false
|
||||
|
||||
}
|
||||
|
||||
@test "ignore: don't display new but ignored tables in dolt diff" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
CREATE TABLE nomatch (pk int);
|
||||
SQL
|
||||
|
||||
run dolt diff
|
||||
run dolt sql -q "SELECT * FROM dolt_ignore AS OF 'start'"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ! "$output" =~ "test1" ]] || false
|
||||
[[ ! "$output" =~ "test2" ]] || false
|
||||
[[ ! "$output" =~ "test3" ]] || false
|
||||
|
||||
[[ "$output" =~ "nomatch" ]] || false
|
||||
! [["$output" =~ "ignoreme"]] || false
|
||||
}
|
||||
|
||||
@test "ignore: don't display new but ignored tables in reverse diff" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
CREATE TABLE nomatch (pk int);
|
||||
SQL
|
||||
|
||||
run dolt diff -R
|
||||
run dolt sql -q "SELECT * FROM dolt_ignore AS OF 'HEAD^'"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
[[ "$output" =~ "nomatch" ]] || false
|
||||
! [["$output" =~ "ignoreme"]] || false
|
||||
}
|
||||
|
||||
@test "ignore: DO display modified ignored tables in dolt diff after staging" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
SQL
|
||||
|
||||
dolt add --force ignoreme
|
||||
|
||||
dolt sql <<SQL
|
||||
INSERT INTO ignoreme VALUES (1);
|
||||
SQL
|
||||
|
||||
run dolt diff
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
echo "$output"
|
||||
|
||||
[[ "$output" =~ "ignoreme" ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: DO display modified ignored tables in reverse diff after staging" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
SQL
|
||||
|
||||
dolt add --force ignoreme
|
||||
|
||||
dolt sql <<SQL
|
||||
INSERT INTO ignoreme VALUES (1);
|
||||
SQL
|
||||
|
||||
run dolt diff -R
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
echo "$output"
|
||||
|
||||
[[ "$output" =~ "ignoreme" ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: DO display modified ignored tables in dolt diff after committing" {
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE ignoreme (pk int);
|
||||
SQL
|
||||
|
||||
dolt add --force ignoreme
|
||||
dolt commit -m "commit1"
|
||||
|
||||
dolt sql <<SQL
|
||||
INSERT INTO ignoreme VALUES (1);
|
||||
SQL
|
||||
|
||||
run dolt diff
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
echo "$output"
|
||||
|
||||
[[ "$output" =~ "ignoreme" ]] || false
|
||||
}
|
||||
|
||||
@test "ignore: detect when equivalent patterns have different values" {
|
||||
|
||||
dolt sql <<SQL
|
||||
INSERT INTO dolt_ignore VALUES
|
||||
("**_test", true),
|
||||
("*_test", false),
|
||||
|
||||
("*_foo", true),
|
||||
("%_foo", false);
|
||||
CREATE TABLE a_test (pk int);
|
||||
CREATE TABLE a_foo (pk int);
|
||||
SQL
|
||||
|
||||
conflict=$(get_conflict_tables)
|
||||
|
||||
echo "$conflict"
|
||||
|
||||
[[ ! -z $(echo "$conflict" | grep "a_test") ]] || false
|
||||
[[ ! -z $(echo "$conflict" | grep "a_foo") ]] || false
|
||||
[[ ! "$output" =~ "test1" ]] || false
|
||||
[[ ! "$output" =~ "test2" ]] || false
|
||||
[[ ! "$output" =~ "test3" ]] || false
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user