По умолчанию в базе данных SQLite не получится увидеть изменения через привычный git diff

git diff
diff --git a/db.sqlite3 b/db.sqlite3
index f622eb24..6e44fa5 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ

Если запустить nano db.sqlite3, то увидим кучу тарабарщины, которая не похожа на структурированные данные. Потому что данные хранятся в бинарном виде. Существует изящный трюк, который можно использовать для решения этой проблемы: используем встроенный в git механизм textconv для снятия дампа базы данных sqlite3 на лету, чтобы отслеживать изменения, используя стандартную команду git diff. Добавьте в конфигурацию тип diff под названием “sqlite3”. Самый простой способ - просто выполнить эти команды:

git config diff.sqlite3.binary true
git config diff.sqlite3.textconv "sh -c 'sqlite3 \$0 .dump'"

Также вы можете добавить этот фрагмент в ~/.gitconfig или .git/config в вашем репозитории:

[diff "sqlite3"]
        binary = true
        textconv = "sqlite3 \$0 .dump"

Далее создайте файл .gitattributes, если его еще нет, и добавьте в него эту строку:

*.sqlite3 diff=sqlite3

Расширение имени файла *.sqlite3 может отличаться в зависимости от софта

Теперь при запуске git diff для sqlite-файла, увидим красиво оформленный diff с изменениями.

Проверим на примере

Создаем новую папку и инициируем пустой репозиторий:

mkdir new-database
cd new-database
git init

Создаем конфигурацию, описанную выше:

git config diff.sqlite3.textconv "sh -c 'sqlite3 \$0 .dump'"
echo '*.sqlite3 diff=sqlite3' > .gitattributes

Далее создаем sqlite3 базу данных, используя интерактивный режим командной строки инструмента sqlite3:

sqlite3 database.sqlite3

Создаем структуру базы:

CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT NOT NULL
);

Далее продолжая в интерактивном режиме, добавим двух пользователей:

INSERT INTO users (name, email) VALUES ('Alice', 'alice@ordinatus.ru');
INSERT INTO users (name, email) VALUES ('Bob', 'bob@ordinatus.ru');

Используем оператор SELECT, чтобы убедиться, что они есть:

SELECT * FROM users;

Такой должен быть результат:

1|Alice|alice@ordinatus.ru
2|Bob|bob@ordinatus.ru

We exit the interactive sqlite3 mode with:

.exit

Теперь делаем коммит базы данных в репозиторий:

git add database.sqlite3
git commit -m "Add database"

Теперь у нас есть git-репозиторий с sqlite3 бинарным файлом, содержащим нашу базу данных. Добавим еще одного пользователя и посмотрим, что произойдет, когда запустим git diff на репозитории.

Переходим в интерактивный режим базы данных sqlite3:

sqlite3 database.sqlite3

Добавляем пользователя:

INSERT INTO users (name, email) VALUES ('Charlie', 'charlie@ordinatus.ru');

Выходим из интерактивного режима:

.exit

Теперь можем запустить и увидеть git diff:

git diff

diff --git a/database.sqlite3 b/database.sqlite3
index 0da3892..1caaa60 100644
--- a/database.sqlite3
+++ b/database.sqlite3
@@ -7,4 +7,5 @@ CREATE TABLE users (
 );
 INSERT INTO users VALUES(1,'Alice','alice@ordinatus.ru');
 INSERT INTO users VALUES(2,'Bob','bob@ordinatus.ru');
+INSERT INTO users VALUES(3,'Charlie','charlie@ordinatus.ru');
 COMMIT;

Видим, что в нашей базе данных появился новый пользователь - как раз то, что нужно.

Если сделать коммит, сможем использовать git log -p, чтобы посмотреть, что именно изменилось между ревизиями. Обратите внимание, что не получится использовать git add -p для добавления изменений: git бвыдаст ошибку, что изменился только двоичный файл.